Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I overload constructors in PHP?

People also ask

Why does PHP not support method overloading?

You cannot overload PHP functions. Function signatures are based only on their names and do not include argument lists, so you cannot have two functions with the same name. Class method overloading is different in PHP than in many other languages. PHP uses the same word but it describes a different pattern.

Can constructors Cannot be overloaded?

A default constructor cannot be overloaded in the same class. This is because once a constructor is defined in a class, the compiler will not create the default constructor. Thus, an attempt to overload the default constructor will effectively remove it from the class. The constructor must not use a different name.

Does PHP have method overloading?

PHP does not support method overloading. In case you've never heard of method overloading, it means that the language can pick a method based on which parameters you're using to call it. This is possible in many other programming languages like Java, C++.


You can't overload ANY method in PHP. If you want to be able to instantiate a PHP object while passing several different combinations of parameters, use the factory pattern with a private constructor.

For example:

public MyClass {
    private function __construct() {
    ...
    }

    public static function makeNewWithParameterA($paramA) {
        $obj = new MyClass(); 
        // other initialization
        return $obj;
    }

    public static function makeNewWithParametersBandC($paramB, $paramC) {
        $obj = new MyClass(); 
        // other initialization
        return $obj;
    }
}

$myObject = MyClass::makeNewWithParameterA("foo");
$anotherObject = MyClass::makeNewWithParametersBandC("bar", 3);

You can use variable arguments to produce the same effect. Without strong typing, it doesn't make much sense to add, given default arguments and all of the other "work arounds."


For completeness, I'll suggest Fluent Interfaces. The idea is that by adding return $this; to the end of your methods you can chain calls together. So instead of

$car1 = new Car('blue', 'RWD');
$car2 = new Car('Ford', '300hp');

(which simply wouldn't work), you can do:

$car = (new Car)
       ->setColor('blue')
       ->setMake('Ford')
       ->setDrive('FWD');

That way you can pick exactly which properties you want to set. In a lot of ways it's similar to passing in an array of options to your initial call:

$car = new Car(['make' => 'Ford', 'seats' => 5]);

True overloading is indeed unsupported in PHP. As @Pestilence mentioned, you can use variable arguments. Some people just use an Associative Array of various options to overcome this.


PHP Manual: Function Arguments, Default Values

I have overcome this simply by using default values for function parameters. In __constuct, list the required parameters first. List the optional parameters after that in the general form $param = null.

class User
{
    private $db;
    private $userInput;

    public function __construct(Database $db, array $userInput = null)
    {
        $this->db = $db;
        $this->userInput = $userInput;
    }
}

This can be instantiated as:

$user = new User($db)

or

$user = new User($db, $inputArray);

This is not a perfect solution, but I have made this work by separating parameters into absolutely mandatory parameters no matter when the object is constructed, and, as a group, optional parameters listed in order of importance.

It works.