PHP [OOP] - 如何手动调用类构造函数?

A.N*_*lam 11 php oop constructor class

请看下面的代码:

01. class Test {
02.     public function __construct($param1, $param2, $param3) {
03.         echo $param1.$param2.$param3;
04.     }
05. }
06. 
07. $params = array('p1','p2','p3');
08. 
09. $ob = new Test;
10. 
11. if(method_exists($ob,'__construct')) {
12.     call_user_func_array(array($ob,'__construct'),$params);
13. }
Run Code Online (Sandbox Code Playgroud)

现在,问题是在09行调用构造函数

但我想在第11-13行手动调用它

可能吗?如果那么怎么样?有什么好主意吗?

Asa*_*aph 23

构造对象时无法阻止构造函数的调用(代码中的第9行).如果__construct()您希望在构建之后推迟某种功能,则应将其移至另一种方法.该方法的一个好名字可能是init().

为什么不这样做呢?

class Test {
    public function __construct($param1, $param2, $param3) {
        echo $param1.$param2.$param3;
    }
}

$ob = new Test('p1', 'p2', 'p3');
Run Code Online (Sandbox Code Playgroud)

编辑:我只是想到一种hacky方式,你可以阻止一个构造函数被调用(某种程度).你可以Test使用一个空的,无操作的构造函数来子类化和覆盖构造函数.

class SubTest extends Test {
    public function __construct() {
        // don't call parent::__construct()
    }

    public function init($param1, $param2, $param3) {
        parent::__construct($param1, $param2, $param3);
    }
}

$ob = new SubTest();
$ob->init('p1', 'p2', 'p3');
Run Code Online (Sandbox Code Playgroud)

如果您正在处理一些由于某种原因无法更改的代码并且需要解决一些写得不好的构造函数的烦人行为,那么这可能是有意义的.


Sar*_*raz 9

注意,如果构造函数(__construct方法)包含通过引用传递的参数,那么函数:

call_user_func_array
Run Code Online (Sandbox Code Playgroud)

将失败并出错.

我建议你改用Reflection类; 这是你如何做到这一点:

// assuming that class file is already included.

$refMethod = new ReflectionMethod('class_name_here',  '__construct');
$params = $refMethod->getParameters();

$re_args = array();

foreach($params as $key => $param)
{
    if ($param->isPassedByReference())
    {
        $re_args[$key] = &$args[$key];
    }
    else
    {
        $re_args[$key] = $args[$key];
    }
}

$refClass = new ReflectionClass('class_name_here');
$class_instance = $refClass->newInstanceArgs((array) $re_args);
Run Code Online (Sandbox Code Playgroud)