你不能在一个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中最好的方法是什么?


当前回答

你可以这样做:

public function __construct($param)
{
    if(is_int($param)) {
         $this->id = $param;
    } elseif(is_object($param)) {
     // do something else
    }
 }

其他回答

public function __construct() {
    $parameters = func_get_args();
    ...
}

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

现在$ parameters将是一个值为'One', 'Two', 3的数组。

编辑,

我可以加上

func_num_args()

会给出函数的参数个数。

你可以这样做:

public function __construct($param)
{
    if(is_int($param)) {
         $this->id = $param;
    } elseif(is_object($param)) {
     // do something else
    }
 }

Kris的回答很好,但正如Buttle Butku评论的那样,新的static()将在PHP 5.3+中被首选。

所以我会这样做(根据克里斯的回答修改):

<?php

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

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

    public static function withRow( array $row ) {
        $instance = new static();
        $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
    }
}

?>

用法:

<?php

$student1 = Student::withID($id);
$student2 = Student::withRow($row);

?>

我还在php.net OOP文档中找到了一个有用的例子。

嗯,很惊讶我还没有看到这个答案,假设我要参加竞选。

class Action {
    const cancelable    =   0;
    const target        =   1
    const type          =   2;

    public $cancelable;
    public $target;
    public $type;


    __construct( $opt = [] ){

        $this->cancelable   = isset($opt[cancelable]) ? $opt[cancelable] : true;
        $this->target       = isset($opt[target]) ?     $opt[target] : NULL;
        $this->type         = isset($opt[type]) ?       $opt[type] : 'action';

    }
}


$myAction = new Action( [
    Action::cancelable => false,
    Action::type => 'spin',
    .
    .
    .
]);

您可以选择将这些选项分离到它们自己的类中,例如扩展脾。

abstract class ActionOpt extends SplEnum{
    const cancelable    =   0;
    const target        =   1
    const type          =   2;
}

我创建这个方法是为了让它不仅在构造函数中使用,而且在方法中使用:

我的构造函数:

function __construct() {
    $paramsNumber=func_num_args();
    if($paramsNumber==0){
        //do something
    }else{
        $this->overload('__construct',func_get_args());
    }
}

我的doSomething方法:

public function doSomething() {
    $paramsNumber=func_num_args();
    if($paramsNumber==0){
        //do something
    }else{
        $this->overload('doSomething',func_get_args());
    }
}

两者都使用这个简单的方法:

public function overloadMethod($methodName,$params){
    $paramsNumber=sizeof($params);
    //methodName1(), methodName2()...
    $methodNameNumber =$methodName.$paramsNumber;
    if (method_exists($this,$methodNameNumber)) {
        call_user_func_array(array($this,$methodNameNumber),$params);
    }
}

所以你可以声明

__construct1($arg1), __construct2($arg1,$arg2)...

or

methodName1($arg1), methodName2($arg1,$arg2)...

等等。

使用时:

$myObject =  new MyClass($arg1, $arg2,..., $argN);

它将调用__constructN,在那里你定义了N个参数

然后 $myObject -> doSomething($arg1, $arg2,..), argM美元)

它会调用doSomethingM,在这里你定义了M个参数;