Re: E_RECOVERABLE_ERROR for "Call to a member function on a non-object"
| From: | Ferenc Kovacs | Date: | Wed, 20 Mar 2013 16:18:41 +0000 |
| Subject: | Re: E_RECOVERABLE_ERROR for "Call to a member function on a non-object" | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-66718@lists.php.net to get a copy of this message | ||
On Wed, Mar 20, 2013 at 5:14 PM, Ferenc Kovacs <tyra3l@gmail.com> 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<https://bugs.php.net/bug.php?id=51882> Call To Member
>> Function on Non-Object Should Throw An Exception
>> *
>> #46601<https://bugs.php.net/bug.php?id=46601>
>> E_RECOVERABLE_ERROR for "Call to a member function on a non-object"
>> * #51848<https://bugs.php.net/bug.php?id=51848Þ±Ì3ì^ëMæÇ
>> _àœ> Non-object
>> method call errors should be catchable with set_error_handler()
>> *
>> #63538<https://bugs.php.net/bug.php?id=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 impossible
>> 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 = $session->getPage()->find('css',
>> '#next');
>> if (empty($button)) {
>> throw new Exception("Could not find #next
>> button");
>> }
>> $button->click()
>>
>> However, this is laborious and easy to overlook. The consequences of
>> forgetting this manual null check seem disproportionately and unnecessarily
>> 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 recovered
>> 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-function-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<http://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 the
> 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=54195&edit=2
>
>
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
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu