rfc:remove_php4_constructors

Differences

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

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
rfc:remove_php4_constructors [2014/11/17 20:40]
levim
rfc:remove_php4_constructors [2015/02/23 04:31]
levim Status: Voting
Line 3: Line 3:
   * Date: 2014-11-17   * Date: 2014-11-17
   * Author: Levi Morrison <levim@php.net>   * Author: Levi Morrison <levim@php.net>
-  * Status: Under Discussion+  * Contributors: Andrea Faulds <ajf@ajf.me> 
 +  * Status: Voting
   * First Published at: http://wiki.php.net/rfc/remove_php4_constructors   * First Published at: http://wiki.php.net/rfc/remove_php4_constructors
  
 ===== Introduction ===== ===== Introduction =====
-PHP 4 constructors are methods that have the same name as the class they are defined in. PHP 5 preserved the ability to use PHP 4 style constructors in some cases. The strangeness of when the constructor is and isn't used increases the mental model for programmers.+PHP 4 constructors are methods that have the same name as the class they are defined in. PHP 5 preserved the ability to use PHP 4 style constructors in some cases; the strangeness of when the constructor is and isn't used increases the mental model for programmers. 
  
 <PHP> <PHP>
Line 28: Line 29:
  
 <PHP> <PHP>
-// Defining __construct before filter makes filter a normal method+// Defining __construct and filter makes filter a normal method
 class Filter { class Filter {
     function __construct() {}     function __construct() {}
Line 36: Line 37:
 } }
  
-//… but the other way raises an E_STRICT +//But defining filter first raises an E_STRICT
 class Filter { class Filter {
  
-    // constructor…+    // Not a constructor…
     function filter($a) {}     function filter($a) {}
  
-    //…until this overrides it and raises E_STRICT+    // This raises E_STRICT
     function __construct() {}     function __construct() {}
 } }
Line 50: Line 50:
  
 ===== Proposal ===== ===== Proposal =====
-This RFC proposes changes for two PHP versions:+PHP 7 will emit ''E_DEPRECATED'' whenever a PHP 4 constructor is defined. When the method name matches the class name, the class is not in a namespace, and a PHP 5 constructor (''<nowiki>__construct</nowiki>'') is not present then an ''E_DEPRECATED'' will be emitted. PHP 8 will stop emitting ''E_DEPRECATED'' and the methods will not be recognized as constructors.
  
-  - **PHP 5.7**: an ''E_DEPRECATED'' notice will be raised whenever a PHP 4 style constructor is defined. Note that this means it will not raise an error in a context where a method shares the same name as the class but is not recognized as a constructor, such as in namespaced classes or in traits. Emitting this ''E_DEPRECATED'' warning will help migration from PHP 5 to PHP 7. Note that the RFC to [[/rfc/switch.default.multiple#proposal|remove multiple default statements from switch blocks]] proposed this same technique. +PHP 7 will also stop emitting ''E_STRICT'' when a method with the same name as the class is present as well as ''<nowiki>__construct</nowiki>''.
-  - **PHP 7.0**: methods with the same name as the class they are defined will not be recognized as constructors in any context; they will be treated as normal methods.+
  
-Some code samples in the [[#examples|Examples]] section show how code is impacted.+Refer to the [[#examples|Examples]] section to see how code is impacted.
  
 ==== Backward Incompatible Changes ==== ==== Backward Incompatible Changes ====
-This RFC will break code that relies on PHP constructors. The solution is to rename the constructors to ''<nowiki>__construct</nowiki>''. This will allow the class to be compatible with PHP 5, but breaks compatibility with PHP 4 completely.+Since an ''E_DEPRECATED'' will be emitted in PHP 7 there may be some backwards compatibility breaks when people use custom error handlers. 
 + 
 +In PHP 8 recognition for old constructors will be outright removed, meaning that anything without a ''<nowiki>__construct</nowiki>'' will not work the same way it used to. The old-style constructor will be considered a normal method and will not be called when the object is constructed. The fix is to rename the constructor to ''<nowiki>__construct</nowiki>''.
  
 ==== Examples ==== ==== Examples ====
Line 64: Line 65:
 class Filter { class Filter {
  
-    // PHP 5.X: filter is a constructor +    // PHP 5: filter is a constructor 
-    // PHP 5.7: filter is a constructor but an E_DEPRECATED is raised +    // PHP 7: filter is a constructor and E_DEPRECATED is raised 
-    // PHP 7.0No errror is raised; filter is a normal method and not a constructor+    // PHP 8: filter is a normal method and is not a constructor; no E_DEPRECATED is raised
     function filter($a) {}     function filter($a) {}
 } }
Line 72: Line 73:
 $filter = new ReflectionMethod('Filter', 'filter'); $filter = new ReflectionMethod('Filter', 'filter');
  
-// PHP 5.X: bool(true) +// PHP 5: bool(true) 
-// PHP 7.0: bool(false)+// PHP 7: bool(true) 
 +// PHP 8: bool(false)
 var_dump($filter->isConstructor()); var_dump($filter->isConstructor());
 </PHP> </PHP>
Line 80: Line 82:
 // function filter is not used as constructor in PHP 5+ // function filter is not used as constructor in PHP 5+
 class Filter { class Filter {
-    // PHP 5.0-5.6: E_STRICT "Redefining already defined constructor" +    // PHP 5: E_STRICT "Redefining already defined constructor" 
-    // PHP 5.7: E_DEPRECATED "Redefining already defined constructor" +    // PHP 7: No error is raised 
-    // PHP 7.0: No errror is raised+    // PHP 8: No error is raised
     function filter($a) {}     function filter($a) {}
     function __construct() {}     function __construct() {}
Line 94: Line 96:
  
     // PHP 5.0.0 - 5.2.13, 5.3.0 - 5.3.2: E_STRICT "Redefining already defined constructor"     // PHP 5.0.0 - 5.2.13, 5.3.0 - 5.3.2: E_STRICT "Redefining already defined constructor"
-    // PHP 5.2.14 - 5.2.17, 5.3.3 - 5.6: No errror is raised +    // PHP 5.2.14 - 5.2.17, 5.3.3 - 5.6: No error is raised 
-    // PHP 5.7: No errror is raised +    // PHP 7: No error is raised 
-    // PHP 7.0: No errror is raised+    // PHP 8: No error is raised
     function filter($a) {}     function filter($a) {}
 } }
 </PHP> </PHP>
  
-===== Proposed PHP Version(s) ===== +<PHP> 
-This RFC targets PHP 7 and PHP 5.NEXT:+class Filter { 
 +    // PHP 5: filter is a constructor 
 +    // PHP 7: filter is a constructor and E_DEPRECATED is raised 
 +    // PHP 8filter is a normal method and is not a constructor; no E_DEPRECATED is raised 
 +    function filter() {} 
 +
 +  
 +class FilterX extends Filter {
  
-PHP 5.7Raise ''E_DEPRECATED'' whenever a PHP 4 style constructor is defined, noting that it will be a normal method in PHP 7 \\ +    function __construct() { 
-PHP 7.0Stop recognizing methods with the same name as the class they are defined in as constructors.+        // PHP 5: Filter::filter is called; no error 
 +        // PHP 7: Filter::filter is called; no error 
 +        // PHP 8"Fatal error: Cannot call constructor" 
 +        parent::__construct(); 
 +    }
  
-===== RFC Impact ===== +}
-This RFC has no impact to SAPI's or extensions.+
  
-==== To Opcache ==== +new FilterX(); 
-Opcache is likely to be unaffected by this proposal, but this has not yet been verified.+</PHP>
  
-===== Open Issues ===== +===== Voting ===== 
-There are some tests that rely on behavior that this RFC would remove to trigger error conditions((See [[https://github.com/php/php-src/blob/f0c926564c5f7de9462d9ca7bd75014b14a63f56/Zend/tests/errmsg_045.phpt|Zend/tests/errmsg_045.phpt]])). These tests would need to find a different error trigger.+This RFC targets PHP 7 and PHP 8Please read the RFC to understand what is being proposed.
  
-===== Proposed Voting Choices ===== +This RFC requires 2/3 vote in favor of deprecating and removing PHP 4 style constructors to pass.
-This RFC requires 2/3 vote in favor of removing PHP 4 style constructors to pass.+
  
-===== Patches and Tests ===== +Do you vote to remove PHP 4 constructors as outlined in this RFC?
-A partial implementation based on the master branch can be found here: https://github.com/php/php-src/pull/901+
  
-The tests for this behavior have not yet been fixedAs mentioned in [[#open_issues|Open Issues]], there are some tests that rely on an E_STRICT being generated to test other behavior; these will need to find a new trigger.+<doodle title="remove_php4_constructors" auth="levim" voteType="single" closed="false"> 
 +   * Yes 
 +   * No 
 +</doodle> 
 + 
 +Voting will close on the evening (UTC-7) of March 6th. 
 + 
 +===== Patches and Tests ===== 
 +An implementation based on the master branch can be found here: https://github.com/php/php-src/pull/1061
  
-===== References ===== 
-TODO: dig up pains caused by PHP 4 constructors in PHP 5 \\ 
-Links to external references, discussions or RFCs 
rfc/remove_php4_constructors.txt · Last modified: 2017/09/22 13:28 (external edit)