rfc:undefined_variable_error_promotion

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:undefined_variable_error_promotion [2022/02/17 14:00] marandallrfc:undefined_variable_error_promotion [2022/03/28 17:52] (current) marandall
Line 1: Line 1:
 ====== PHP RFC: Undefined Variable Error Promotion ====== ====== PHP RFC: Undefined Variable Error Promotion ======
-  * Version: 0.9 +  * Version: 1 
-  * Date: 2022-02-22+  * Date: 2022-02-17
   * Author: Mark Randall marandall@php.net   * Author: Mark Randall marandall@php.net
-  * Status: Draft+  * Status: Accepted
   * Target: PHP 9.0   * Target: PHP 9.0
   * First Published at: https://wiki.php.net/rfc/undefined_variable_error_promotion   * First Published at: https://wiki.php.net/rfc/undefined_variable_error_promotion
  
 ===== Introduction ===== ===== Introduction =====
-Undefined variables are those that have not yet been initialised with a value prior to being read. Accessing an undefined variable currently emits an E_WARNING and treats the variable as if it were a null, but does not otherwise interrupt execution, allowing code execution to continue unabated, but likely in an unintended state.+Undefined variables are those that have not yet been initialised with a value prior to being read. Accessing an undefined variable currently emits an E_WARNING "Warning: Undefined variable $varname" and treats the variable as if it were a null, but does not otherwise interrupt execution, allowing code execution to continue unabated, but likely in an unintended state.
  
-Although a custom error handler can already be used to raise an Error exception, this requires additional userland code to configure. The need to support calling a custom error handler does itself also introduce additional complexity into the engine, leading  to "increasingly complex games" to keep it working.+Although a custom error handler can already be used to raise an Error exception, this requires additional userland code to configure, when instead we should be aiming to provide a safer experience by default. The need to support calling a custom error handler does itself also introduce additional complexity into the engine, leading  to "increasingly complex games" to keep it working (see "Benefits"). 
 + 
 +**RFC History / Previous Votes** 
 + 
 +This change was last discussed during the Engine Warnings RFC (https://wiki.php.net/rfc/engine_warnings) where it received 56% in favour of making this behaviour an Error exception. It is likely that the only reason this vote failed to reach a supermajority at the time was because the condition was previously a notice, and some felt the jump from notice to error was too great for one version. Accessing undefined variables will have been a warning for 5+ years by the time this RFC would come into effect.
  
 ===== Proposal ===== ===== Proposal =====
 This RFC proposes that accessing an undefined variable is rendered illegal behaviour in the next major version of PHP, and will result in an Error exception being thrown if it occurs. This RFC proposes that accessing an undefined variable is rendered illegal behaviour in the next major version of PHP, and will result in an Error exception being thrown if it occurs.
 +
 +For the purposes of this RFC, accessing a variable means to use the variable in such a way that the engine attempts to read its value for use in an expression, without accounting for possibly being unset. These can be identified by the warning "Warning: Undefined variable $varname".
 +
 +isset / empty / null coalesce DO account for undefined values and such are not covered by this RFC.
  
 Undefined variable access can come about in one of 3 main ways: Undefined variable access can come about in one of 3 main ways:
 +
 +**Mechanism 1.** 
  
 The variable only becomes defined when executing certain branching code paths, for example setting a value within an if statement, or within anything which might include an if statement under the hood, such as a loop. The variable only becomes defined when executing certain branching code paths, for example setting a value within an if statement, or within anything which might include an if statement under the hood, such as a loop.
Line 29: Line 39:
 </code> </code>
  
-A typo in the variable name.+**Mechanism 2.**  
 + 
 +A typo in the variable name. 
  
 <code php> <code php>
Line 35: Line 47:
   echo 'Welcome, ' . $naame;   echo 'Welcome, ' . $naame;
 </code> </code>
 +
 +The above example shows a typo when reading the value, but consider also a typo when writing the value, that led to initializing the wrong variable, leaving the intended one uninitialized.
 +
 +<code php>
 +  if ($user->admin) { 
 +     $restricted = false;
 +  } else { 
 +     $restrictedd = true;
 +  }
 +  
 +  if ($restricted) { 
 +     die('You do not have permission to be here');
 +  }
 +</code>
 +
 +**Mechanism 3.** 
  
 Accessing a variable for use with a post-increment operator $foo++ sometimes used with counters (as post-increment on null is special-cased). Accessing a variable for use with a post-increment operator $foo++ sometimes used with counters (as post-increment on null is special-cased).
Line 51: Line 79:
 Of these 3 mechanisms, the first two are almost always unintentional bugs, and while the third can sometimes be a deliberate action, it too is often the result of a coding error. Of these 3 mechanisms, the first two are almost always unintentional bugs, and while the third can sometimes be a deliberate action, it too is often the result of a coding error.
  
-Error conditions 1 and 3 both have fully backwards compatible solutions already available, which simply require initialising the variable to a sensible default prior to its use.  +If for some reason the null behaviour is desired, a simple backwards compatible solution is available, the author needs only to initialize the variable with null prior to its use. It is expected that in many cases a more logical alternative would exist, such as initializing to zero, false, or empty string, depending on the context.  
  
 <code php> <code php>
Line 98: Line 126:
 Although the target version is mandated by our traditional breaking changes policy, it is also the intent of this RFC to give multiple years of notice that this change will be coming, affording the greatest opportunity for developers to modify their code in anticipation of this change. Although the target version is mandated by our traditional breaking changes policy, it is also the intent of this RFC to give multiple years of notice that this change will be coming, affording the greatest opportunity for developers to modify their code in anticipation of this change.
  
-A minor change may be included in the next minor version to change the existing warning message to indicate the warning will become an error in 9.0.+A minor change will be included in the next minor version to alter the existing warning message to indicate the warning will become an error in 9.0. 
 + 
 + 
 +===== Unaffected Functionality ===== 
 +If the code does not currently emit a "Warning: Undefined variable $varname" then it is out of scope for this RFC. This RFC does NOT apply to array indexes. 
 + 
 +===== Vote ===== 
 +Vote opened 2022-03-14, vote closes 2022-03-28 
 + 
 +<doodle title="Promote Undefined Variables to Throw an Error" auth="marandall" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle> 
 + 
 +Meta vote for reasoning of voting against:
  
-===== Proposed Voting Choices ===== +<doodle title="Main reason for voting against if you did?" auth="marandall" voteType="single" closed="true"> 
-Yes No to promote to Error.+   * Using undefined variables is a legitimate coding style 
 +   * Backwards compatibility breaks 
 +   * Would be in favour, but not in 9.0 
 +   * Something else 
 +</doodle>
  
 ===== References ===== ===== References =====
rfc/undefined_variable_error_promotion.1645106445.txt.gz · Last modified: 2022/02/17 14:00 by marandall