Лучший способ сделать несколько конструкторов в PHP

Cookie автоматически обрабатываются браузером при совершении вызова Ajax таким образом, нет никакой потребности в JavaScript для бездельничания с cookie.

328
задан Jannie Theunissen 8 November 2009 в 22:43
поделиться

8 ответов

Я бы, вероятно, сделал что-то вроде этого:

<?php

class Student
{
    public function __construct() {
        // allocate your stuff
    }

    public static function withID( $id ) {
        $instance = new self();
        $instance->loadByID( $id );
        return $instance;
    }

    public static function withRow( array $row ) {
        $instance = new self();
        $instance->fill( $row );
        return $instance;
    }

    protected function loadByID( $id ) {
        // do query
        $row = my_awesome_db_access_stuff( $id );
        $this->fill( $row );
    }

    protected function fill( array $row ) {
        // fill all properties from array
    }
}

?>

Тогда, если мне нужен Студент, у которого я знаю ID:

$student = Student::withID( $id );

Или если у меня есть массив строки db:

$student = Student::withRow( $row );

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

452
ответ дан 23 November 2019 в 00:48
поделиться

Насколько мне известно, в PHP не поддерживается перегрузка. Вы можете только перегрузить методы get и set свойств с помощью overload (); ( http://www.php.net/manual/en/overload.examples.basic.php )

0
ответ дан 23 November 2019 в 00:48
поделиться

, как указано в других комментариях, поскольку php не поддерживает перегрузку, обычно избегаются "уловки проверки типов" в конструкторе и используется заводской шаблон intead

, т.е.

$myObj = MyClass::factory('fromInteger', $params);
$myObj = MyClass::factory('fromRow', $params);
4
ответ дан 23 November 2019 в 00:48
поделиться

Другой вариант - использовать аргументы по умолчанию в конструкторе, подобные этому

class Student {

    private $id;
    private $name;
    //...

    public function __construct($id, $row=array()) {
        $this->id = $id;
        foreach($row as $key => $value) $this->$key = $value;
    }
}

Это означает, что вам нужно создать экземпляр со строкой, подобной этой: $ student = new Student ($ row ['id'], $ row) , но сохраняет ваш конструктор красивым и чистым.

С другой стороны, если вы хотите использовать полиморфизм, вы можете создать два класса, например:

class Student {

    public function __construct($row) {
         foreach($row as $key => $value) $this->$key = $value;
    }
}

class EmptyStudent extends Student {

    public function __construct($id) {
        parent::__construct(array('id' => $id));
    }
}
4
ответ дан 23 November 2019 в 00:48
поделиться

Вы можете сделать что-то вроде этого:

public function __construct($param)
{
    if(is_int($param)) {
         $this->id = $param;
    } elseif(is_object($param)) {
     // do something else
    }
 }
13
ответ дан 23 November 2019 в 00:48
поделиться
public function __construct() {
    $parameters = func_get_args();
    ...
}

$o = new MyClass('One', 'Two', 3);

Теперь $ paramters будет массивом со значениями 'One', 'Two', 3.

Edit,

Я могу добавить, что

func_num_args()

предоставит вам количество параметров функции.

22
ответ дан 23 November 2019 в 00:48
поделиться

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

class Student 
{
   protected $id;
   protected $name;
   // etc.

   public function __construct($idOrRow){
    if(is_int($idOrRow))
    {
        $this->id = $idOrRow;
        // other members are still uninitialized
    }
    else if(is_array($idOrRow))
    {
       $this->id = $idOrRow->id;
       $this->name = $idOrRow->name;
       // etc.  
    }
}
41
ответ дан 23 November 2019 в 00:48
поделиться

Вы можете сделать что-то вроде следующего, что действительно просто и очень чисто:

public function __construct()    
{
   $arguments = func_get_args(); 

   switch(sizeof(func_get_args()))      
   {
    case 0: //No arguments
        break; 
    case 1: //One argument
        $this->do_something($arguments[0]); 
        break;              
    case 2:  //Two arguments
        $this->do_something_else($arguments[0], $arguments[1]); 
        break;            
   }
}
4
ответ дан 23 November 2019 в 00:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: