rfc:deprecate-bareword-strings

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:deprecate-bareword-strings [2017/01/29 19:15] – tidy up a few loose edges imsoprfc:deprecate-bareword-strings [2018/03/01 23:25] (current) – RFC was implemented in PHP 7.2 carusogabriel
Line 1: Line 1:
 ====== PHP RFC: Deprecate and Remove Bareword (Unquoted) Strings ====== ====== PHP RFC: Deprecate and Remove Bareword (Unquoted) Strings ======
-  * Version: 1.0 +  * Version: 1.1 
-  * Date: 2017-01-29+  * Date: 2017-03-05
   * Author: Rowan Collins rowan.collins@gmail.com   * Author: Rowan Collins rowan.collins@gmail.com
-  * Status: In Discussion+  * Status: Implemented (in PHP 7.2)
   * First Published at: http://wiki.php.net/rfc/deprecate-bareword-strings   * First Published at: http://wiki.php.net/rfc/deprecate-bareword-strings
  
Line 62: Line 62:
   - In PHP 7.2, raise the severity of the message "Use of undefined constant" from E_NOTICE to E_WARNING   - In PHP 7.2, raise the severity of the message "Use of undefined constant" from E_NOTICE to E_WARNING
   - Immediately document the fallback from bareword to string as deprecated in the manual   - Immediately document the fallback from bareword to string as deprecated in the manual
-  - In PHP 7.2, change the text of the message from ''Use of undefined constant %s - assumed '%s''' to ''Use of undefined constant %s; assumed '%s', but this will change in a future version of PHP''+  - In PHP 7.2, change the text of the message from ''Use of undefined constant %s - assumed '%s''' to ''Use of undefined constant %s; assumed '%s' (this will throw an error in a future version of PHP)''
   - In PHP 8.0, remove the fallback, and replace the ''E_WARNING'' with a thrown ''Error'' with message ''Use of undefined constant %s''   - In PHP 8.0, remove the fallback, and replace the ''E_WARNING'' with a thrown ''Error'' with message ''Use of undefined constant %s''
  
-It might seem surprising to raise an ''E_WARNING'' with text suggesting deprecation, rather than an ''E_DEPRECATED''However, we need to balance two conflicting aims:+===== E_WARNING vs E_DEPRECATED ===== 
 + 
 +It might seem surprising to raise an ''E_WARNING'' with text suggesting deprecation, rather than an ''E_DEPRECATED''This was chosen because we need to balance two aims:
  
   * If a user is relying on the fallback to string, we should communicate that this feature is officially deprecated and slated for removal.   * If a user is relying on the fallback to string, we should communicate that this feature is officially deprecated and slated for removal.
-  * If a user was actually intending to reference a constant or keyword, we should increase the chance they will see the message.+  * If a user was actually intending to reference a constant or keyword, we should increase the chance they will see the message. Furthermore, this is necessarily a run-time error - a constant may be defined in some code paths and not others - so some instances may show up only in production.  
 + 
 +To make the message visible, we want to use an error level likely to be enabled both in development and production configurations. Since ''E_DEPRECATED'' is actually //less// likely to be enabled than ''E_NOTICE'', switching to ''E_DEPRECATED'' would effectively "downgrade" the visibility of the message. Our two aims are therefore in direct conflict. 
 + 
 +This RFC takes the position that it is more likely that people will trigger this behaviour by mistake, so the priority is to make such a mistake obvious; thus ''E_WARNING'' is the correct severity. 
 + 
 +The proposed wording is also an attempt to balance these two possibilities. The use of parentheses is to avoid the awkward phrasing "in a future version of PHP in..." which would otherwise appear in the full output:
  
-In my opinion, the latter is more likely, and more configurations will have logging or display of ''E_WARNING'' than either ''E_NOTICE'' or ''E_DEPRECATED'', so that is the most appropriate severity.+<blockquote>Warning: Use of undefined constant FOO - assumed 'FOO(this will throw an error in a future version of PHP) in foo.php on line 1</blockquote>
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 76: Line 84:
 This change is quite deliberately a change to current behaviour.  This change is quite deliberately a change to current behaviour. 
  
-Browsing [[https://github.com/phplang/php-past/|the archived copies of PHP source code]], we can see that the behaviour has been present since at least PHP 3.0. Early PHP 3 betas apparently [[https://github.com/phplang/php-past/blob/PHP-3.0b4/language-parser.y#L559|treated all unknown barewords as strings]]; however, before the final release, both built-in and user-defined constants were added as a new language feature, and [[https://github.com/phplang/php-past/blob/PHP-3.0/language-parser.y#L553|the first version of the current notice was added]]. It's unclear to me whether the hand-crafted lexer and parser in PHP 2.0 treated bare words as strings or errors; if anyone has it successfully compiled and would like to check, let me know.+Browsing [[https://github.com/phplang/php-past/|the archived copies of PHP source code]] shows that the current behaviour was added late in the development of PHP 3.0. In PHP 2.0, an unquoted string was simply a syntax error, but early PHP 3 betas added a feature to [[https://github.com/phplang/php-past/blob/PHP-3.0b4/language-parser.y#L559|treat all barewords which weren't keywords as strings]]. Before the final release, both built-in and user-defined constants were added as a new language feature, and [[https://github.com/phplang/php-past/blob/PHP-3.0/language-parser.y#L553|the first version of the current notice was added]]. 
  
-However, the old source code also includes the documentation with which it shipped, in which I can find no mention of this behaviour, and no examples which take advantage of it.+The old source code also includes the documentation with which PHP 3 shipped, which seem to have no mention of this behaviour, and no examples which take advantage of it.
  
 As mentioned earlier, it has been //discouraged// in the manual since 2001, so it could be argued that it is //already deprecated//. This RFC takes the conservative view that there should still be a standard period of deprecation before removing it. As mentioned earlier, it has been //discouraged// in the manual since 2001, so it could be argued that it is //already deprecated//. This RFC takes the conservative view that there should still be a standard period of deprecation before removing it.
Line 98: Line 106:
 ===== Open Issues ===== ===== Open Issues =====
  
-  * The exact text of the E_WARNING message. 
   * Appropriate locations in the manual to document the deprecation, since it is not clearly documented as a current feature.   * Appropriate locations in the manual to document the deprecation, since it is not clearly documented as a current feature.
  
 ===== Unaffected PHP Functionality ===== ===== Unaffected PHP Functionality =====
  
-  * Unquoted array keys within a double-quoted string will remain valid, e.g. ''"Item bar is $foo[bar]"''+  * Unquoted array keys within a double-quoted string will remain valid, e.g. ''"Item bar is $foo[bar]"''; since this //never// looks up a constant, it does not suffer from the same ambiguities and subtle bugs as the main syntax discussed here. 
 +  * Defining arrays in query strings will continue to be unquoted, e.g. ''test.php?foo[bar]=42''; this has no ambiguity at all, since there is no scope where constants could be defined in order to populate it.
   * Undefined class constants, namespaced constants, and explicit constant references prefixed by ''\'' will continue to throw errors as currently.   * Undefined class constants, namespaced constants, and explicit constant references prefixed by ''\'' will continue to throw errors as currently.
  
Line 111: Line 119:
  
  
-===== Proposed Voting Choices =====+===== Voting =====
  
-A single yes/no vote requiring a 2/3 majority.+Voting opened on 2017-03-08, and will close on 2017-03-22 at 22:00 UTC
  
-In PHP 7.2, replace the "Undefined constant" ''E_NOTICE'' with an ''E_WARNING'' stating that the fallback is deprecated; and in PHP 8.0, remove the fallback and replace the ''E_WARNING'' with an ''Error''.+The vote requires a 2/3 majority to accept the proposal.
  
 +Voting is on the following proposal:
 +
 +  - In PHP 7.2, raise the severity of the message "Use of undefined constant" from E_NOTICE to E_WARNING, and change the text of the message to ''Use of undefined constant %s; assumed '%s' (this will throw an error in a future version of PHP)''
 +  - In PHP 8.0, remove the fallback, and replace the ''E_WARNING'' with a thrown ''Error'' with message ''Use of undefined constant %s''
  
-===== Patches and Tests =====+<doodle title="Raise severity of undefined constants to E_WARNING in 7.2, and Error in 8.0?" auth="imsop" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle>
  
-None yet. 
  
 ===== Implementation ===== ===== Implementation =====
  
-None yet.+  * Pull Request implementing the change itself: https://github.com/php/php-src/pull/2404  
 +  * Merged into master: https://github.com/php/php-src/commit/1b565f1393f82e0ce0c94806cc7f52c6d9c5e87d 
 +  * Pull Request to the Language Spec documenting the new behaviour: https://github.com/php/php-langspec/pull/193
  
 ===== Rejected Features ===== ===== Rejected Features =====
  
 None yet. None yet.
rfc/deprecate-bareword-strings.txt · Last modified: 2018/03/01 23:25 by carusogabriel