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> 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

Reply via email to