# RFC: Remove PHP 4 Constructors

- Status: Implemented (PHP 7.0)
- Authors: Levi Morrison levim@php.net
- Date: 2014-11-17
- Version: 1.0
- Original: https://wiki.php.net/rfc/remove_php4_constructors
- Page: https://externals.io/rfc/remove_php4_constructors
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### remove_php4_constructors (closed)

Yes: 50 · No: 4

Voters: ab (No), aharvey (Yes), ajf (Yes), brandon (Yes), bwoebi (Yes), crodas (Yes), daverandom (Yes), davey (Yes), diegopires (Yes), dm (Yes), dmitry (Yes), dragoonis (Yes), frozenfire (Yes), galvao (Yes), guilhermeblanco (Yes), indeyets (Yes), jedibc (Yes), jgmdev (Yes), jpauli (Yes), jwage (Yes), kalle (Yes), kinncj (Yes), krakjoe (Yes), laruence (No), lcobucci (Yes), leigh (Yes), levim (Yes), lstrojny (Yes), mariuz (Yes), mbeccati (Yes), mfonda (Yes), mike (Yes), mrook (Yes), nikic (Yes), olemarkus (Yes), pajoye (Yes), patrickallaert (Yes), pauloelr (Yes), peehaa (Yes), philstu (Yes), ralphschindler (Yes), rdlowrey (Yes), rdohms (Yes), remi (No), salathe (Yes), santiagolizardo (Yes), sobak (Yes), stas (No), thekid (Yes), treffynnon (Yes), tyrael (Yes), yohgaki (Yes), yunosh (Yes), zeev (Yes)

## Discussions on the mailing list

- [\[RFC\] Remove PHP 4 Constructors](https://externals.io/message/78969.md) — started on 2014-11-18, 96 messages
- [\[RFC\] Remove PHP 4 Constructors Update](https://externals.io/message/82072.md) — started on 2015-02-06, 4 messages
- [\[RFC\] Deprecate properties using var](https://externals.io/message/82525.md) — started on 2015-02-12, 6 messages
- [\[VOTE\] Remove PHP 4 Constructors](https://externals.io/message/83541.md) — started on 2015-02-23, 5 messages

---

## 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
class Filter {
 
    // A constructor in PHP 4 and 5
    function filter($a) {}
}
```

```php
// Namespaced classes do not recognize PHP 4 constructors
namespace NS;
class Filter {
 
    // Not a constructor
    function filter($a) {}
}
```

```php
// 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

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 (`__construct`) 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 7 will also stop emitting `E_STRICT` when a method with the same name as the class is present as well as `__construct`.

Refer to the [Examples](#examples) section to see how code is impacted.

### Backward Incompatible Changes

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 `__construct` 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 `__construct`.

### Examples

```php
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($a) {}
}
 
$filter = new ReflectionMethod('Filter', 'filter');
 
// PHP 5: bool(true)
// PHP 7: bool(true)
// PHP 8: bool(false)
var_dump($filter->isConstructor());
```

```php
// function filter is not used as constructor in PHP 5+
class Filter {
    // PHP 5: E_STRICT "Redefining already defined constructor"
    // PHP 7: No error is raised
    // PHP 8: No error is raised
    function filter($a) {}
    function __construct() {}
}
```

```php
// 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 error is raised
    // PHP 7: No error is raised
    // PHP 8: No error is raised
    function filter($a) {}
}
```

```php
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() {}
}
 
class FilterX extends Filter {
 
    function __construct() {
        // 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();
    }
 
}
 
new FilterX();
```

## Voting

This RFC targets PHP 7 and PHP 8. Please read the RFC to understand what is being proposed.

This RFC requires 2/3 vote in favor of deprecating and removing PHP 4 style constructors to pass.

Do you vote to remove PHP 4 constructors as outlined in this RFC?

**Vote: remove\_php4\_constructors** — Yes: 50 · No: 4 (closed)

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>
