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/18 19:14]
levim
rfc:remove_php4_constructors [2015/03/10 19:20]
levim Close 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: Accepted
   * 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 49: 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 63: 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 and 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 71: 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 79: 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: 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) {}
     function __construct() {}     function __construct() {}
Line 93: 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) {}
 } }
Line 101: Line 104:
  
 <PHP> <PHP>
-class Filter { +class Filter { 
 +    // PHP 5: filter is a constructor 
 +    // PHP 7: filter is a constructor and E_DEPRECATED is raised 
 +    // PHP 8: filter is a normal method and is not a constructor; no E_DEPRECATED is raised
     function filter() {}     function filter() {}
 } }
    
 class FilterX extends Filter { class FilterX extends Filter {
-    function __construct() { 
  
-        // PHP 5.X: Filter::filter is called; no error +    function __construct() { 
-        // PHP 7.0"Fatal error: Cannot call constructor" +        // PHP 5: Filter::filter is called; no error 
-        //          This happens because Filter no longer has a constructor +        // PHP 7: Filter::filter is called; no error 
-        //          An (in draft) RFC proposal to allow this to always succeedhttps://wiki.php.net/rfc/default_ctor+        // PHP 8"Fatal errorCannot call constructor"
         parent::__construct();         parent::__construct();
     }     }
 +
 } }
  
Line 119: Line 125:
 </PHP> </PHP>
  
-==== Impact to Opcache ==== +===== Voting ===== 
-Opcache is likely to be unaffected by this proposal, but this has not yet been verified.+This RFC targets PHP 7 and PHP 8. Please read the RFC to understand what is being proposed.
  
-===== Open Issues ===== +This RFC requires 2/3 vote in favor of deprecating and removing PHP 4 style constructors to pass.
-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.+
  
-Documentation should remove unnecessary cognitive load for new learners, but preserve enough information for people searching for the old behavior.+Do you vote to remove PHP 4 constructors as outlined in this RFC?
  
-===== Voting ===== +<doodle title="remove_php4_constructors" auth="levim" voteType="single" closed="true"> 
-This RFC targets PHP 7 and PHP 5.7:+   * Yes 
 +   * No 
 +</doodle>
  
-PHP 5.7: Raise ''E_DEPRECATED'' whenever a PHP 4 style constructor is defined, noting that it will be a normal method in PHP \\ +Voting will close on the evening (UTC-7of March 6th.
-PHP 7.0: Stop recognizing methods with the same name as the class they are defined in as constructors. +
- +
-This RFC requires 2/3 vote in favor of removing PHP 4 style constructors to pass.+
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
-A partial implementation based on the master branch can be found here: https://github.com/php/php-src/pull/901 +An implementation based on the master branch can be found here: https://github.com/php/php-src/pull/1061
- +
-The tests for this behavior have not yet been fixed. As 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.+
  
-===== 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)