Fixing PHP4 constructors for PHP7

PHP 7 deprecates PHP4-style constructors . In PHP4, class constructor methods had the same name as the class: ​

<?php
class Foo
{
    function Foo()
    {
        //some initialization code
    }
}
?>

This was bad when switching base classes; you did not only have to change the class' extends declaration, but also calls to the parent constructor. PHP5 then introduced the generic __construct method name for class constructors, which solved the problem. ​

PHP7 will output a deprecation message when a class with a PHP4-style constructor is loaded (not necessarily used): ​

PHP Deprecated:  Methods with the same name as their class will not be
constructors in a future version of PHP;
SubClass has a deprecated constructor in /path/to/file.php on line 15​

Fixing by renaming​

So you're maintaining code - maybe a library - that has such a old-style constructor: ​

<?php
class OldClass
{
    public function OldClass()
    {
        echo "OldClass constructor\n";
    }
}
?>

Note that this code works well, even in PHP7. PHP7 logs the deprecation message, but the code still works. ​

Users of your library report the deprecation notice, and you decide to bring the code up-to-date with PHP7 by renaming the constructor method: ​

<?php
class OldClass
{
    public function __construct()
    {
        echo "OldClass constructor\n";
    }
}
?>

You release a new version, and suddenly applications fatally break: ​

PHP Fatal error:  Call to undefined method SubClass::OldClass()
in /path/to/file.php on line 14​

This is because other applications rely on the existence of the old constructor: ​

<?php
class SubClass extends OldClass
{
    public function SubClass()
    {
        $this->OldClass();
    }
}
 
new SubClass();
?>

A real fix​

To not break everyone using your library, you have to keep backwards compatibility: Add the PHP5-style constructor, but keep the PHP4-style one. ​

class OldClass
{
    public function __construct()
    {
        echo "OldClass constructor\n";
    }
 
    public function OldClass()
    {
        self::__construct();
    }
}
?>

With that change, your code will not emit deprecation messages anymore while keeping compatibility with older applications: ​

<?php
class SubClass extends OldClass
{
    public function SubClass()
    {
        $this->OldClass();
    }
}
 
class OtherClass extends OldClass
{
    public function __construct()
    {
        parent::__construct();
    }
}
 
new SubClass();
new OtherClass();
?>

Constructor parameters​

You may need to pass constructor parameters, too.

class OldClass
{
    public function __construct($foo, $bar = null)
    {
        echo "OldClass constructor\n";
    }
 
    public function OldClass($foo, $bar = null)
    {
        self::__construct($foo, $bar);
    }
}
?>

Notes​

PHP Strict standards: Redefining already defined constructor for class​

This happens if you put the PHP4 constructor before __construct. The warning will not be raised when __construct is defined first. ​

Written by Christian Weiske.

Comments? Please send an e-mail.