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:
-
Do I need to create an RFC for this change, or could I just create a pull request in GitHub?
-
Would anyone object to this change? For example on backwards-compatibility grounds?
-
If I put the effort in to create the RFC and a patch, would it be likely to be accepted?
-
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"
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.comhttp://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
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"
anE_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_processI would like to know:
Do I need to create an RFC for this change, or could I just
create a pull request in GitHub?
Would anyone object to this change? For example on
backwards-compatibility grounds?
If I put the effort in to create the RFC and a patch, would it be
likely to be accepted?
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"Thanks for your time,
Rich
Richard Bradley
Tel : 020 7485 7500 ext 3230 | Fax : 020 7485 7575softw i re
Sunday Times Best Small Companies 2012 - 6th in the UK
Web : www.softwire.comhttp://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
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
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"
anE_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_processI would like to know:
Do I need to create an RFC for this change, or could I just
create a pull request in GitHub?
Would anyone object to this change? For example on
backwards-compatibility grounds?
If I put the effort in to create the RFC and a patch, would it
be likely to be accepted?
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"Thanks for your time,
Rich
Richard Bradley
Tel : 020 7485 7500 ext 3230 | Fax : 020 7485 7575softw i re
Sunday Times Best Small Companies 2012 - 6th in the UK
Web : www.softwire.comhttp://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 2SB1, 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 fatasIn 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
internals@lists.php.net/msg64708.html" rel="nofollow" target="_blank">http://www.mail-archive.com/internals@lists.php.net/msg64708.html
--
Ferenc Kovács
@Tyr43l - http://tyrael.hu
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.
Do I need to create an RFC for this change, or could I just create a pull request in GitHub?
1, yes
OK, will do
Would anyone object to this change? For example on backwards-compatibility grounds?
2, yes
Could you be more specific?
I was hoping to head off some of the objections in this email thread, or at least to avoid coding up a patch if it is certain to be rejected.
Could you elaborate on what the objections might be, and what measures I could put in place to overcome them?
If I put the effort in to create the RFC and a patch, would it be likely to be accepted?
3, depends on the patch
Of course. Could you be more specific? Are there any particular issues the patch would need to address to be accepted? Anyone in particular I need to convince to get this merged in? Or should I just do my best and trust in the RFC voting system?
Has anyone attempted this change before and had it rejected, or given up?
4, yes, at least there were a couple of discussions in general about removing/converting some of the fatals to recoverable fatals
Thanks: do you have any pointers for where I can find this?
I get no relevant hits on wiki.php.net or on the "internals" list search at marc.info for search terms like "E_RECOVERABLE_ERROR" or "Call to a member function on a non-object".
ps: there were also https://bugs.php.net/bug.php?id=54195&edit=2
Thanks; I'll add this to the list of relevant bugs. I'll update all the bugs if / when the RFC gets resolved.
Best,
Rich
Richard Bradley
Tel : 020 7485 7500 ext 3230 | Fax : 020 7485 7575
softwire
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
Would anyone object to this change? For example on
backwards-compatibility grounds?
2, yes
Could you be more specific?
I was hoping to head off some of the objections in this email thread, or
at least to avoid coding up a patch if it is certain to be rejected.
Could you elaborate on what the objections might be, and what measures I
could put in place to overcome them?
I can't talk for the others, but my experience on the list tells me that
this isn't an easy problem, otherwise it would be solved already, and some
of the voters are conservative when comes to changing the status quo, so
personally I would be surprised if nobody would object such a change, but
this shouldn't hold you back, the important thing is to have the majority
of the votes, you can't satisfy everybody.
your best bet is to have a clear and unbiased RFC and a nice patch.
If I put the effort in to create the RFC and a patch, would
it be likely to be accepted?
3, depends on the patch
Of course. Could you be more specific? Are there any particular issues the
patch would need to address to be accepted? Anyone in particular I need to
convince to get this merged in? Or should I just do my best and trust in
the RFC voting system?
the latter.
Has anyone attempted this change before and had it rejected,
or given up?
4, yes, at least there were a couple of discussions in general about
removing/converting some of the fatals to recoverable fatalsThanks: do you have any pointers for where I can find this?
I get no relevant hits on wiki.php.net or on the "internals" list search
at marc.info for search terms like "E_RECOVERABLE_ERROR" or "Call to a
member function on a non-object".
there were some good discussion in the
http://grokbase.com/t/php/php-internals/128335vjrj/error-handling-brainstormingthread
(see for example the reply from Nikita where he also mentioned the
cases when the fatal isn't really a fatal, just hard to recover from
sanely).
some other related discussion happened in
internals@lists.php.net/msg60652.html" rel="nofollow" target="_blank">http://www.mail-archive.com/internals@lists.php.net/msg60652.html
and the closest thread that I can found would be
http://grokbase.com/t/php/php-internals/122nywvc5f/exceptions-for-method-on-non-object-rather-than-fatal-desired-feature
Has anyone attempted this change before and had it rejected, or given up?
4, yes, at least there were a couple of discussions in general about removing/converting some of the fatals to recoverable fatals
Thanks: do you have any pointers for where I can find this?there were some good discussion in the http://grokbase.com/t/php/php-internals/128335vjrj/error-handling-brainstorming thread
(see for example the reply from Nikita where he also mentioned the cases when the fatal isn't really a fatal, just hard to recover from sanely).
some other related discussion happened in internals@lists.php.net/msg60652.html" rel="nofollow" target="_blank">http://www.mail-archive.com/internals@lists.php.net/msg60652.html
Thanks, that’s very helpful.
and the closest thread that I can found would be
http://grokbase.com/t/php/php-internals/122nywvc5f/exceptions-for-method-on-non-object-rather-than-fatal-desired-feature
That seems to be the exact same proposal, which is encouraging in some ways, but discouraging in others :-)
The thread was quickly derailed with discussion of turning errors into exceptions; which I don't think is needed here. We just need to change the category of this error (and ensure that the interpreter is in a suitable state to recover from the error, if the user chooses to do so).
I have emailed Ralf Lang to see how far he got after that thread.
see for example the reply from Nikita
That message seemed to be related to converting errors to exceptions.
I don't propose to do that; I just hope to convert some E_ERRORs to E_RECOVERABLE_ERROR
there were some good discussion in the http://grokbase.com/t/php/php-internals/128335vjrj/error-handling-brainstorming thread
I have emailed Derick Rethans about this comment:
http://grokbase.com/t/php/php-internals/128335vjrj/error-handling-brainstorming#201208272kxvjtb16cvqpd4n8aeweqtwk8
where he suggested there was a specific reason that the remaining E_ERRORs could not be converted to E_RECOVERABLE_ERRORs.
I'll copy any replies to the list.
Best,
Rich
Richard Bradley
Tel : 020 7485 7500 ext 3230 | Fax : 020 7485 7575
softwire
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