Jan*_*sen 329 php constructor multiple-constructors
您不能在PHP类中放置两个带有唯一参数签名的__construct函数.我想这样做:
class Student 
{
   protected $id;
   protected $name;
   // etc.
   public function __construct($id){
       $this->id = $id;
      // other members are still uninitialized
   }
   public function __construct($row_from_database){
       $this->id = $row_from_database->id;
       $this->name = $row_from_database->name;
       // etc.
   }
}
在PHP中执行此操作的最佳方法是什么?
Kri*_*ris 454
我可能会这样做:
<?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 );
从技术上讲,你不是构建多个构造函数,只是静态辅助方法,但是你可以通过这种方式避免构造函数中的大量意大利面条代码.
tim*_*hew 82
Kris的解决方案非常好,但我发现工厂和流畅的风格更好:
<?php
class Student
{
    protected $firstName;
    protected $lastName;
    // etc.
    /**
     * Constructor
     */
    public function __construct() {
        // allocate your stuff
    }
    /**
     * Static constructor / factory
     */
    public static function create() {
        $instance = new self();
        return $instance;
    }
    /**
     * FirstName setter - fluent style
     */
    public function setFirstName( $firstName) {
        $this->firstName = $firstName;
        return $this;
    }
    /**
     * LastName setter - fluent style
     */
    public function setLastName( $lastName) {
        $this->lastName = $lastName;
        return $this;
    }
}
// create instance
$student= Student::create()->setFirstName("John")->setLastName("Doe");
// see result
var_dump($student);
?>
Daf*_*aff 41
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.  
    }
}
Bjö*_*örn 22
public function __construct() {
    $parameters = func_get_args();
    ...
}
$o = new MyClass('One', 'Two', 3);
现在$ paramters将是一个值为'One','Two',3的数组.
编辑,
我可以补充一点
func_num_args()
将为您提供该功能的参数数量.
Nas*_*jim 17
正如这里已经显示的那样,multiple在PHP 中声明构造函数的方法有很多种,但是没有correct一种方法可以这样做(因为PHP技术上不允许这样做).但它并没有阻止我们破解这个功能......这是另一个例子:
<?php
class myClass {
    public function __construct() {
        $get_arguments       = func_get_args();
        $number_of_arguments = func_num_args();
        if (method_exists($this, $method_name = '__construct'.$number_of_arguments)) {
            call_user_func_array(array($this, $method_name), $get_arguments);
        }
    }
    public function __construct1($argument1) {
        echo 'constructor with 1 parameter ' . $argument1 . "\n";
    }
    public function __construct2($argument1, $argument2) {
        echo 'constructor with 2 parameter ' . $argument1 . ' ' . $argument2 . "\n";
    }
    public function __construct3($argument1, $argument2, $argument3) {
        echo 'constructor with 3 parameter ' . $argument1 . ' ' . $argument2 . ' ' . $argument3 . "\n";
    }
}
$object1 = new myClass('BUET');
$object2 = new myClass('BUET', 'is');
$object3 = new myClass('BUET', 'is', 'Best.');
希望这可以帮助.:)
yan*_*nis 15
从版本5.4开始,PHP支持特征.这不是您正在寻找的,但基于特征的简单方法将是:
trait StudentTrait {
    protected $id;
    protected $name;
    final public function setId($id) {
        $this->id = $id;
        return $this;
    }
    final public function getId() { return $this->id; }
    final public function setName($name) {
        $this->name = $name; 
        return $this;
    }
    final public function getName() { return $this->name; }
}
class Student1 {
    use StudentTrait;
    final public function __construct($id) { $this->setId($id); }
}
class Student2 {
    use StudentTrait;
    final public function __construct($id, $name) { $this->setId($id)->setName($name); }
}
我们最终得到两个类,每个构造函数一个,这有点适得其反.为了保持一定的理智,我会投入工厂:
class StudentFactory {
    static public function getStudent($id, $name = null) {
        return 
            is_null($name)
                ? new Student1($id)
                : new Student2($id, $name)
    }
}
所以,这一切都归结为:
$student1 = StudentFactory::getStudent(1);
$student2 = StudentFactory::getStudent(1, "yannis");
这是一种非常冗长的方法,但它可以非常方便.
And*_*c ॐ 13
你可以这样做:
public function __construct($param)
{
    if(is_int($param)) {
         $this->id = $param;
    } elseif(is_object($param)) {
     // do something else
    }
 }
这是一个优雅的方法来做到这一点。创建特征,在给定参数数量的情况下启用多个构造函数。您只需将参数数量添加到函数名称“__construct”。所以一个参数将是“__construct1”,两个“__construct2”......等等。
trait constructable
{
    public function __construct() 
    { 
        $a = func_get_args(); 
        $i = func_num_args(); 
        if (method_exists($this,$f='__construct'.$i)) { 
            call_user_func_array([$this,$f],$a); 
        } 
    } 
}
class a{
    use constructable;
    public $result;
    public function __construct1($a){
        $this->result = $a;
    }
    public function __construct2($a, $b){
        $this->result =  $a + $b;
    }
}
echo (new a(1))->result;    // 1
echo (new a(1,2))->result;  // 3
另一种选择是像这样在构造函数中使用默认参数
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));
    }
}
| 归档时间: | 
 | 
| 查看次数: | 172626 次 | 
| 最近记录: |