rfc:catchable-call-to-member-of-non-object

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:catchable-call-to-member-of-non-object [2014/04/26 14:40] thekidrfc:catchable-call-to-member-of-non-object [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
  
 ====== PHP RFC: Catchable "call to a member function of a non-object" ====== ====== PHP RFC: Catchable "call to a member function of a non-object" ======
-  * Version: 0.8+  * Version: 1.1
   * Date: 2014-04-26   * Date: 2014-04-26
   * Author: Timm Friebe <thekid@php.net>   * Author: Timm Friebe <thekid@php.net>
-  * Status: In Draft+  * Status: Accepted
   * First Published at: https://wiki.php.net/rfc/catchable-call-to-member-of-non-object   * First Published at: https://wiki.php.net/rfc/catchable-call-to-member-of-non-object
 +
 +**Note: This RFC has been superseded by the [[https://wiki.php.net/rfc/engine_exceptions_for_php7|engine exceptions]] proposal.**
  
 ===== Introduction ===== ===== Introduction =====
Line 15: Line 17:
 </PHP> </PHP>
  
-If you want to run PHP as a webserver itself, fatal errors are problematic. For a long story on why you would want to do that in the first place, see http://marcjschmidt.de/blog/2014/02/08/php-high-performance.html+One situation in which fatal errors are problematic is if you want to run PHP as a webserver itself. For a long story on why you would want to do that in the first place, see http://marcjschmidt.de/blog/2014/02/08/php-high-performance.html
 + 
 +Other situtations are described in the [[https://wiki.php.net/rfc/engine_exceptions#issues_with_fatal_errors|Engine Exceptions RFC]].
  
 ===== Proposal ===== ===== Proposal =====
Line 40: Line 44:
 This behavior is consistent with how type hints work. Framework authors can turn this into exceptions if they wish. This behavior is consistent with how type hints work. Framework authors can turn this into exceptions if they wish.
  
-This proposal adds an optional return type declaration to function declarations including closures, functions, generators, interface method declarations and class declarations. This RFC does not change the existing type declarations nor does it add new ones (see [[#differences_from_past_rfcs|differences from past RFCs]]). +==== Example: Exceptions ====
- +
-==== Example ====+
 The following error handler could be embedded into frameworks: The following error handler could be embedded into frameworks:
  
Line 65: Line 67:
 </PHP> </PHP>
  
 +==== Example: Without exceptions ====
 +This could be a way for people preferring not to use exceptions and instead to exit the script directly, but get a stacktrace instead of just the fatal error message:
 +
 +<PHP>
 +set_error_handler(function($code, $message) {
 +  echo "*** Error #$code: $message\n";
 +  debug_print_backtrace();
 +  exit(0xFF);
 +}, E_RECOVERABLE_ERROR);
 + 
 +$m= new some_db_model();
 +$row= $m->find(42); // null, deleted concurrently
 +$row->delete();
 +</PHP>
  
 ==== Differences from Past RFCs ==== ==== Differences from Past RFCs ====
 This proposal doesn't go as far as the controversial RFC [[engine_exceptions|RFC: Engine exceptions]]. This proposal doesn't go as far as the controversial RFC [[engine_exceptions|RFC: Engine exceptions]].
 +
 +==== Inner workings ==== 
 +
 +Taken this code:
 +
 +<PHP>
 +function a($comparator) {
 +  $result= $comparator->compare(1, 2);
 +  // ...
 +}
 +</PHP>
 +
 +You can unwind this to something like:
 +
 +  function a($comparator) {
 +    1: ZEND_INIT_METHOD_CALL $comparator 'compare'
 +    2: ZEND_SEND_VAL         1
 +    3: ZEND_SEND_VAL         2
 +    4: ZEND_DO_FCALL_BY_NAME
 +    5: ZEND_ASSIGN           $result
 +    // ...
 +  }
 +
 +The handling on checking whether the method is callable happends inside
 +the opline #1 (''ZEND_INIT_METHOD_CALL''). The opcode handler for it 
 +checks its first argument (here: ''$comparator'') whether it is an object
 +or not. In case it's not, the following happens:
 +
 +  - A recoverable error is triggered. Should the script exit here, there's nothing more to be done, this is just as it was before.
 +  - In case the script continues, all the oplines are skipped until we find the ''FCALL_BY_NAME'' opcode. This is comparable to jumping forward just as, e.g., the ''ZEND_JMP'' instruction would.
 +  - The return value is set to ''ZVAL_NULL()''.
 +  - The control is handed back to the executor, which then continues with the ''ASSIGN'' opcode
 +  - The engine is again in full control; if an exception was raised by the handler, that leads to the known behavior.
  
 ===== Other Impact ===== ===== Other Impact =====
Line 95: Line 144:
 Ideas for future work include: Ideas for future work include:
  
-  * Also allowing to catch +  * Also allowing to catch and handle other fatal errors 
-  * Allowing nullable types(such as <php>?DateTime</php>). This is discussed in related RFC: [[rfc:nullable_typehints|Declaring Nullable Types]] + 
-  Unifying the reflection type API by introducing a ''ReflectionType'' class that both parameter and return types can use. +===== Vote ===== 
-  Improving parameter variance. Currently parameter types are invariant while they could be contravariant. +Voting started 2014-06-29 and ended 2014-07-30.  
-  * Improving runtime performance by doing type analysis. + 
-  * Updating documentation to use the new return type syntax.+<doodle title="Catchable Call to a member function bar() on non-object" auth="thekid" voteType="single" closed="true"> 
 +   Yes 
 +   No 
 +</doodle> 
  
 ===== References ===== ===== References =====
-  * PHP Bugs [[https://bugs.php.net/bug.php?id=46601|46601]], [[https://bugs.php.net/bug.php?id=51882|51882]] and [[https://bugs.php.net/bug.php?id=51848]] 51848 - bugs which would be fixed by this+  * PHP Bugs [[https://bugs.php.net/bug.php?id=46601|46601]], [[https://bugs.php.net/bug.php?id=51882|51882]] and [[https://bugs.php.net/bug.php?id=51848|51848]]- bugs which would be fixed by this
   * PHP Bug [[https://bugs.php.net/bug.php?id=54195|54195]] - related, motivates necessity   * PHP Bug [[https://bugs.php.net/bug.php?id=54195|54195]] - related, motivates necessity
   * HHVM [[https://github.com/facebook/hhvm/blob/master/hphp/test/quick/method-non-object.php.expectf|throws a BadMethodCallException]] in these situations    * HHVM [[https://github.com/facebook/hhvm/blob/master/hphp/test/quick/method-non-object.php.expectf|throws a BadMethodCallException]] in these situations 
 +  * [[http://news.php.net/php.internals/73814|Mailing list announcement]] 
 +  * [[rfc/returntypehinting|Return type hinting RFC]] - related work: Some fatal errors can be prevented by setting return types.
rfc/catchable-call-to-member-of-non-object.1398523245.txt.gz · Last modified: 2017/09/22 13:28 (external edit)