rfc:remove_php4_constructors

This is an old revision of the document!


PHP RFC: Remove PHP 4 Constructors

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.

class Filter {
 
    // A constructor in PHP 4 and 5
    function filter($a) {}
}
// Namespaced classes do not recognize PHP 4 constructors
namespace NS;
class Filter {
 
    // Not a constructor
    function filter($a) {}
}
// Defining __construct and filter makes filter a normal method
class Filter {
    function __construct() {}
 
    // Not a constructor
    function filter($a) {}
}
 
//But defining filter first raises an E_STRICT
class Filter {
 
    // Not a constructor…
    function filter($a) {}
 
    // This raises E_STRICT
    function __construct() {}
}

Proposal

This RFC proposes changes for two PHP versions:

  1. 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 remove multiple default statements from switch blocks proposed this same technique.
  2. 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 section show how code is impacted.

Backward Incompatible Changes

This RFC will break code that relies on PHP 4 constructors. The solution is to rename the constructors to __construct. This will allow the class to be compatible with PHP 5, but breaks compatibility with PHP 4 completely.

Examples

class Filter {
 
    // PHP 5.X: filter is a constructor
    // PHP 5.7: filter is a constructor and an E_DEPRECATED is raised
    // PHP 7.0: No errror is raised; filter is a normal method and not a constructor
    function filter($a) {}
}
 
$filter = new ReflectionMethod('Filter', 'filter');
 
// PHP 5.X: bool(true)
// PHP 7.0: bool(false)
var_dump($filter->isConstructor());
// function filter is not used as constructor in PHP 5+
class Filter {
    // PHP 5.0-5.6: E_STRICT "Redefining already defined constructor"
    // PHP 5.7: E_DEPRECATED "Redefining already defined constructor"
    // PHP 7.0: No errror is raised
    function filter($a) {}
    function __construct() {}
}
// function filter is not used as constructor in PHP 5+
class Filter {
    function __construct() {}
 
    // 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.7: No errror is raised
    // PHP 7.0: No errror is raised
    function filter($a) {}
}

RFC Impact

This RFC has no impact to SAPI's or extensions.

To Opcache

Opcache is likely to be unaffected by this proposal, but this has not yet been verified.

Open Issues

There are some tests that rely on behavior that this RFC would remove to trigger error conditions1). These tests would need to find a different error trigger.

Voting

This RFC targets PHP 7 and PHP 5.7:

PHP 5.7: Raise E_DEPRECATED whenever a PHP 4 style constructor is defined, noting that it will be a normal method in PHP 7
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

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 fixed. As mentioned in 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.1416257196.txt.gz · Last modified: 2017/09/22 13:28 (external edit)