我想打电话给一个班级'构造函数通过可调用的,所以我有以下代码:
$callable = array('Foo', '__construct');
但是调用它会引发以下错误:
Fatal error: Non-static method Foo::__construct() cannot be called statically
我理解构造函数不是静态方法,但我不能使用现有实例来调用新实例的构造函数(因为它只会再次调用现有对象上的构造函数),是否存在以任何方式调用像这样的构造函数?
答案 0 :(得分:3)
如果您正在寻找一种动态选择要构建的类的简单方法,则可以使用带有new
关键字的变量名称,如下所示:
$inst = new $class_name;
// or, if the constructor takes arguments, provide those in the normal way:
$inst = new $class_name('foo', 'bar');
但是,如果你需要的是一种将构造函数传递给已经期望可调用的东西的方法,我能想到的最好的方法是将它包装在一个匿名函数中:
$callable = function() { return new Foo; }
call_user_func( $callable );
答案 1 :(得分:2)
如果你真的必须使用call_user_func
,这可能有效,但不清楚你为什么要这样做:
$reflection = new ReflectionClass("Foo");
$instance = $reflection->newInstanceWithoutConstructor();
call_user_func(array($instance, '__construct'));
答案 2 :(得分:0)
正如@MauganRa在评论中提到的更正确的答案是使用\ReflectionClass::newInstance()
或\ReflectionClass::newInstanceArgs()
。我认为这应该用完整的答案来表达。
现在,如果您想将此作为回调传递并使用call_user_func()
或call_user_func_array()
,请尝试以下操作:
$callable = [new \ReflectionClass('C'), 'newInstance'];
或者更加充实的例子:
class Car {
private $color;
private $size;
public function __construct($color, $size) {
$this->color = $color;
$this->size = $size;
}
public function describe() {
return "A $this->size $this->color car.";
}
}
$callable = [new \ReflectionClass('Car'), 'newInstance'];
$cars = [];
$cars[] = call_user_func($callable, 'red', 'big')->describe();
$cars[] = call_user_func_array($callable, ['blue', 'small'])->describe();
var_export($cars);
我不知道另一个/更好的解决方案。