Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:66718 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 1067 invoked from network); 20 Mar 2013 16:18:46 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 20 Mar 2013 16:18:46 -0000 Authentication-Results: pb1.pair.com smtp.mail=tyra3l@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=tyra3l@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.210.173 as permitted sender) X-PHP-List-Original-Sender: tyra3l@gmail.com X-Host-Fingerprint: 209.85.210.173 mail-ia0-f173.google.com Received: from [209.85.210.173] ([209.85.210.173:49362] helo=mail-ia0-f173.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id D4/C8-46127-461E9415 for ; Wed, 20 Mar 2013 11:18:44 -0500 Received: by mail-ia0-f173.google.com with SMTP id h37so1561813iak.4 for ; Wed, 20 Mar 2013 09:18:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:x-received:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; bh=mn0sl9inhji2VUrlhy1Xp8HnY+21MUQixxvXn+Z8cTk=; b=P2bmIObSq9JU1lQ5jivWYz8STyA9j6HC9n8PFQuxlk88oQo+vti1xq0/3BB+OT8qv+ jX4X4FsGjs4RTJn/hDHjhV9wWDJmpA+RhwRfPRWhQp4UpSFF/n4vPpTV6EneRzUid9nQ b/3XHDoYIZqPybA46VYB+VBPHC6wmb+2DM8+ldkZuhYJ8SPZ6NwxnWFAl3f6eGJTUILk HWQXmK6hokipLcMyHFnzri/gJpCvbQT+JHDMulbeF87R+URKIB118bAb5e0+Lj/7/p/8 cuZ7piqKNN1vU5QQagWSr7YmYdm+bM1Kl39cov78Xt7MoF+f/PEOfQLUpTIv15gUdu5u mujA== MIME-Version: 1.0 X-Received: by 10.50.12.229 with SMTP id b5mr4597887igc.105.1363796321327; Wed, 20 Mar 2013 09:18:41 -0700 (PDT) Received: by 10.50.114.137 with HTTP; Wed, 20 Mar 2013 09:18:41 -0700 (PDT) In-Reply-To: References: Date: Wed, 20 Mar 2013 17:18:41 +0100 Message-ID: To: Richard Bradley Cc: "internals@lists.php.net" Content-Type: multipart/alternative; boundary=14dae9340b494763ac04d85d9364 Subject: Re: [PHP-DEV] E_RECOVERABLE_ERROR for "Call to a member function on a non-object" From: tyra3l@gmail.com (Ferenc Kovacs) --14dae9340b494763ac04d85d9364 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Wed, Mar 20, 2013 at 5:14 PM, Ferenc Kovacs wrote: > > > > On Wed, Mar 20, 2013 at 3:37 PM, Richard Bradley < > Richard.Bradley@softwire.com> wrote: > >> I'd like to patch PHP to make "Call to a member function on a non-object= " >> an E_RECOVERABLE_ERROR instead of an E_ERROR. >> >> I have not been able to find any previous discussion of making this >> change, but there are several PHP bugs requesting it: >> * #51882 Call To Member >> Function on Non-Object Should Throw An Exception >> * #46601 >> E_RECOVERABLE_ERROR for "Call to a member function on a non-object" >> * #51848 Non-object >> method call errors should be catchable with set_error_handler() >> * #63538 "Call to >> undefined function" should be catchable >> >> I have read >> https://blogs.oracle.com/opal/entry/the_mysterious_php_rfc_process >> >> I would like to know: >> >> 1. Do I need to create an RFC for this change, or could I just >> create a pull request in GitHub? >> >> 2. Would anyone object to this change? For example on >> backwards-compatibility grounds? >> >> 3. If I put the effort in to create the RFC and a patch, would it >> be likely to be accepted? >> >> 4. Has anyone attempted this change before and had it rejected, or >> given up? >> >> Technical summary: >> >> If you make a member function call on a null value (or any other >> non-object), a fatal error is raised. This makes it completely impossibl= e >> to recover from null-ref errors. >> For example, in a Behat test suite, you might write: >> $session->getPage()->find('css', '#next')->click() >> >> If the "find" function returns NULL, then the "->click()" call is fatal. >> Your test suite will not be able to continue at the next test, and all >> further output will be lost. >> >> The simple workaround is to check the value before invoking a function, >> i.e.: >> $button =3D $session->getPage()->find('css', '#next'); >> if (empty($button)) { >> throw new Exception("Could not find #nex= t >> button"); >> } >> $button->click() >> >> However, this is laborious and easy to overlook. The consequences of >> forgetting this manual null check seem disproportionately and unnecessar= ily >> severe. >> >> It would be more convenient if the null dereference was an >> E_RECOVERABLE_ERROR, which would allow scripts to convert the error into= an >> exception, and continue the script at the next suitable point, via a >> "catch". >> >> The documentation for E_ERROR at >> http://php.net/manual/en/errorfunc.constants.php says that these errors >> are "Fatal run-time errors. These indicate errors that can not be recove= red >> from, such as a memory allocation problem. Execution of the script is >> halted." >> >> It doesn't seem to me that dereferencing "null" with "->" would be an >> error that "can not be recovered from, such as a memory allocation >> problem". In fact, the interpreter should be in a very predictable state= , >> and quite capable of continuing if the user's script requests it. >> This error is a much better match for the description of >> E_RECOVERABLE_ERROR from the same page: "a probably dangerous error >> occurred, but did not leave the Engine in an unstable state" >> >> See also >> http://stackoverflow.com/questions/15502559/php-turn-call-to-a-member-fu= nction-on-a-non-object-into-exception >> >> Thanks for your time, >> >> >> Rich >> >> >> >> >> Richard Bradley >> Tel : 020 7485 7500 ext 3230 | Fax : 020 7485 7575 >> >> softw i re >> Sunday Times Best Small Companies 2012 - 6th in the UK >> Web : www.softwire.com | Addr : 325 Highgate >> Studios, 53-79 Highgate Road, London NW5 1TL >> Softwire Technology Limited. Registered in England no. 3824658. >> Registered Office : 13 Station Road, London N3 2SB >> > > 1, yes > 2, yes > 3, depends on the patch > 4, yes, at least there were a couple of discussions in general about > removing/converting some of the fatals to recoverable fatas > > In general there are cases where the cause of the error isn't a fatal one= , > but it would leave the engine in a half-baked state and usually it is > easier to fatal out than implement a proper state recover/reset so that t= he > whole thing won't blow up to your face at the next execution step. > > ps: there were also https://bugs.php.net/bug.php?id=3D54195&edit=3D2 > > btw. there is discussion going on about this generic problem currently: http://news.php.net/php.cvs/71635 http://www.mail-archive.com/internals@lists.php.net/msg64708.html --=20 Ferenc Kov=C3=A1cs @Tyr43l - http://tyrael.hu --14dae9340b494763ac04d85d9364--