Почему я не могу перегружать конструкторы в PHP?

Я отказался от всякой надежды на возможность перегрузить мои конструкторы в PHP, поэтому мне действительно хотелось знать, почему.

Есть ли даже причина для этого? Создает ли он по своей сути плохой код? Широко признан ли языковой дизайн, чтобы он не позволял, или другие языки лучше, чем PHP?

Ответ 1

Вы можете использовать аргументы переменной для получения такого же эффекта. Без сильного ввода текста не имеет смысла добавлять, учитывая аргументы по умолчанию и все другие "работы вокруг".

Ответ 2

Вы не можете перегружать ЛЮБОЙ метод в PHP. Если вы хотите создать экземпляр объекта PHP при передаче нескольких различных комбинаций параметров, используйте шаблон factory с помощью частного конструктора.

Например:

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

Ответ 3

Истинная перегрузка действительно не поддерживается в PHP. Как упоминалось в @Pestilence, вы можете использовать переменные аргументы. Некоторые люди просто используют Ассоциативный массив различных вариантов для преодоления этого.

Ответ 4

Для полноты я предложу Свободные интерфейсы. Идея состоит в том, что, добавляя return $this; в конец ваших методов, вы можете объединять вызовы вместе. Так что вместо

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

(что просто не сработает), вы можете сделать:

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

Таким образом, вы можете выбрать, какие именно свойства вы хотите установить. Во многих отношениях это похоже на передачу массива параметров для вашего первоначального вызова:

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

Ответ 5

Руководство PHP: Аргументы функций, значения по умолчанию

Я преодолел это просто, используя значения по умолчанию для параметров функции. В __constuct сначала укажите требуемые параметры. Перечислите необязательные параметры после этого в общем виде $param = null.

class User
{
    private $db;
    private $userInput;

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

Это может быть указано как:

$user = new User($db)

или

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

Это не идеальное решение, но я сделал эту работу, разделив параметры на абсолютно обязательные параметры независимо от того, когда объект сконструирован, и, как группа, дополнительные параметры перечислены в порядке важности.

Он работает.

Ответ 6

они говорят эту работу:

<?php
class A
{
    function __construct()
    {
        $a = func_get_args();
        $i = func_num_args();
        if (method_exists($this,$f='__construct'.$i)) {
            call_user_func_array(array($this,$f),$a);
        }
    }

    function __construct1($a1)
    {
        echo('__construct with 1 param called: '.$a1.PHP_EOL);
    }

    function __construct2($a1,$a2)
    {
        echo('__construct with 2 params called: '.$a1.','.$a2.PHP_EOL);
    }

    function __construct3($a1,$a2,$a3)
    {
        echo('__construct with 3 params called: '.$a1.','.$a2.','.$a3.PHP_EOL);
    }
}
$o = new A('sheep');
$o = new A('sheep','cat');
$o = new A('sheep','cat','dog');

// results:
// __construct with 1 param called: sheep
// __construct with 2 params called: sheep,cat
// __construct with 3 params called: sheep,cat,dog
?>

и, похоже, все довольны этим, но для меня это не сработало... если вы его заработаете, его один вид перегрузки тоже...

он принимает все аргоменты и передает их в конструктор вторичных функций...

Ответ 7

<?php
//php do not automatically call parent class constructor at all if child class has constructor so you have to call parent class constructor explicitly, however parent class constructor is called automatically if child class has no constructor
class MyClass 
{
    function construct1($value1)
    {
        echo "<br/> dummy constructor is called with 1 arguments and it is $value1";
    }
    function construct2($value1,$value2)
    {
        echo "<br/> dummy constructor is called with 2 arguments and it is $value1, $value2";
    }
    function construct3($value1,$value2,$value3)
    {
        echo "<br/> dummy constructor is called with 3 arguments and it is $value1, $value2 , $value3";
    } 
    public function __construct()
    {
        $NoOfArguments = func_num_args(); //return no of arguments passed in function
        $arguments = func_get_args();
        echo "<br/> child constructor is called $NoOfArguments";
        switch ($NoOfArguments) {
            case 1:
                 self::construct1($arguments[0]);
                break;
            case 2:
                self::construct2($arguments[0],$arguments[1]);
                break;

            case 3:
                self::construct3($arguments[0],$arguments[1],$arguments[2]);
                break;

            default:
                echo "Invalid No of arguments passed";
                break;
        }
    }


}
$c = new MyClass();
$c2 = new MyClass("ankit");
$c2 = new MyClass("ankit","Jiya");
$c2 = new MyClass("ankit","Jiya","Kasish");

? >

Ответ 8

Я действительно не специалист по ООП, но, насколько я понимаю, перегрузка означает способность метода действовать по-разному в зависимости от параметров, которые он получает в качестве входных данных. Это очень возможно с PHP, вы просто не объявляете типы ввода, поскольку PHP не имеет сильной типизации, и вся перегрузка выполняется во время выполнения, а не во время компиляции.

Ответ 9

Вы можете использовать условные операторы в своем конструкторе, а затем выполнять свою задачу. Например.

  class Example
  {
      function __construct($no_of_args)

      {// lets assume 2
          switch($no_of_args)
          {
              case 1:
                // write your code
              break;
              case 2:
                //write your 2nd set of code
              break;
              default:
           //write your default statement
         }
      }
   }

    $object1 = new Example(1);  // this will run your 1st case
    $object2 = new Example(2);  // this will run your 2nd case

и т.д.

Ответ 10

Конечно, вы можете перегрузить любую функцию в PHP, используя магические методы __call() и __callStatic(). Это немного сложно, но реализация может сделать именно то, что вы ищете. Вот ресурс на официальном сайте PHP.net:

https://www.php.net/manual/en/language.oop5.overloading.php#object.call

А вот пример, который работает как для статических, так и нестатических методов:

class MethodTest
{
    public function __call($name, $arguments)
    {
        // Note: value of $name is case sensitive.
        echo "Calling object method '$name' "
             . implode(', ', $arguments). "\n";
    }

    /**  As of PHP 5.3.0  */
    public static function __callStatic($name, $arguments)
    {
        // Note: value of $name is case sensitive.
        echo "Calling static method '$name' "
             . implode(', ', $arguments). "\n";
    }
}

$obj = new MethodTest;
$obj->runTest('in object context');

MethodTest::runTest('in static context');  // As of PHP 5.3.0

И вы можете применить это к конструкторам, используя следующий код в __construct():

$clsName = get_class($this);
$clsName->methodName($args);

Довольно просто. И вы можете захотеть реализовать __clone(), чтобы сделать копию клона класса с методом, который вы вызывали, без функции, которую вы вызывали в каждом случае...

Ответ 11

Насколько мне известно, перегрузка конструктора в PHP недопустима, просто потому, что разработчики PHP не включили эту функциональность - это одна из многих жалоб на PHP.

Я слышал о трюках и обходных решениях, но истинной перегрузки в смысле ООП не хватает. Возможно, в будущих версиях он будет включен.

Ответ 12

Я думаю, что мы можем также использовать конструктор с аргументами по умолчанию как потенциальный заменитель перегрузки конструктора в PHP.

Тем не менее, очень грустно, что истинная перегрузка конструктора не поддерживается в PHP.

Ответ 13

<?php

    class myClass {

        public $param1 = 'a';
        public $param2 = 'b';

        public function __construct($param1 = NULL, $param2 = NULL) {

            if ($param1 == NULL && $param2 == NULL) {
//                $this->param1 = $param1;
//                $this->param2 = $param2;
            } elseif ($param1 == NULL && $param2 !== NULL) {
//                $this->param1 = $param1;
                $this->param2 = $param2;
            } elseif ($param1 !== NULL && $param2 == NULL) {
                $this->param1 = $param1;
//                $this->param2 = $param2;                
            } else {
                $this->param1 = $param1;
                $this->param2 = $param2;
            }

        }

    }

//    $myObject  = new myClass();
//    $myObject  = new myClass(NULL, 2);
    $myObject  = new myClass(1, '');
//    $myObject  = new myClass(1, 2);

    echo $myObject->param1;
    echo "<br />";
    echo $myObject->param2;

?>