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();
?>

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.