programing tip

PHP에서 생성자를 오버로드 할 수없는 이유는 무엇입니까?

itbloger 2020. 8. 30. 07:48
반응형

PHP에서 생성자를 오버로드 할 수없는 이유는 무엇입니까?


나는 PHP에서 내 생성자를 오버로드 할 수 있다는 모든 희망을 버렸다. 그래서 내가 정말로 알고 싶은 것은 .

이유가 있나요? 본질적으로 나쁜 코드를 생성합니까? 그것을 허용하지 않는 것이 널리 받아 들여지는 언어 디자인입니까, 아니면 PHP보다 다른 언어가 더 좋습니까?


변수 인수 를 사용하여 동일한 효과를 생성 할 수 있습니다 . 강력한 타이핑이 없으면 기본 인수와 다른 모든 "해결 방법"이 주어지면 추가하는 것이별로 의미가 없습니다.


PHP에서는 어떤 메서드도 오버로드 할 수 없습니다. 매개 변수의 여러 조합을 전달하면서 PHP 객체를 인스턴스화하려면 private 생성자와 함께 팩토리 패턴을 사용하십시오.

예를 들면 :

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

진정한 오버로딩은 실제로 PHP에서 지원되지 않습니다. @Pestilence가 언급했듯이 변수 인수를 사용할 수 있습니다. 어떤 사람들은이를 극복하기 위해 다양한 옵션의 연관 배열을 사용합니다.


완전성을 위해 Fluent Interfaces를 제안 합니다. 아이디어는 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]);

PHP Manual : 함수 인수, 기본값

함수 매개 변수에 기본값을 사용하여 간단히 극복했습니다. 에서 __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);

이것은 완벽한 솔루션은 아니지만 객체가 생성되는시기와 상관없이 매개 변수를 절대적으로 필수 매개 변수로 분리 하고, 그룹 으로 중요도 순으로 나열된 선택적 매개 변수를 분리하여이 작업을 수행했습니다 .

효과가있다.


그들은이 작품을 말한다 :

<?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
?>

그리고 모든 사람들이 그것에 만족하는 것 같지만 저에게는 작동하지 않았습니다 ... 작동하게한다면 그것의 한 종류의 과부하도 ...

모든 인수를 가져 와서 보조 함수 생성자에 전달합니다.


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

?>


I'm really no OOP expert, but as I understand it overloading means the ability of a method to act differently depending in the parameters it receives as input. This is very much possible with PHP, you just don't declare the input types since PHP does not have strong typing, and all the overloading is done at runtime instead of compile time.


You can use conditional statements in your constructor and then perform your task. Eg.

  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

and so on...


You can of course overload any function in PHP using __call() and __callStatic() magic methods. It is a little bit tricky, but the implementation can do exactly what your are looking for. Here is the resource on the official PHP.net website:

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

And here is the example which works for both static and non-static methods:

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

And you can apply this to constructors by using the following code in the __construct():

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

Pretty easy. And you may want to implement __clone() to make a clone copy of the class with the method that you called without having the function that you called in every instance...


As far as I know, constructor overloading in PHP is not allowed, simply because the developers of PHP did not include that functionality - this is one of the many complaints about PHP.

I've heard of tricks and workarounds, but true overloading in the OOP sense is missing. Maybe in future versions, it will be included.


I think we can also use constructor with default arguments as a potential substitute to constructor overloading in PHP.

Still, it is really sad that true constructor overloading is not supported in PHP.


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

?>

참고URL : https://stackoverflow.com/questions/2169448/why-cant-i-overload-constructors-in-php

반응형