使用call_user_func函数,通过传入字符串函数,可以调用自定义函数,并且支持引用。
1.mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
调用第一个参数提供的自定义函数,后面的参数为自定义函数的参数,返回自定义函数的结果
function say($word)
{
echo $word;
}
call_user_func('say', 'hello world'); //hello world
使用call_user_func可以执行一个类的某个方法,而且可以给方法传参数,它跟实例化一个类再调用方法有什么区别呢?看下面的例子。
class A
{
public function __Construct($a,$b,$c)
{
echo 'Construct'.$a.$b.$c;
}
public function test($a,$b,$c)
{
echo ' test'.$a.$b.$c;
}
}
$a = new A(1,2,3);
$a->test(1,2,3);
call_user_func(['A','test'],1,2,3);
类A有一个构造方法,如果用实例化的方式new A,会执行构造函数,而使用call_user_func的方式调用test方法,并没有出发构造函数,虽然都可以执行到方法,这就是两者的区别。
那么在有的情况下,并不能直接实例化一个类,希望通过其他方式去得到一个类,而且能够执行类的构造方法怎么办?
此时可以使用类的反射类和newInstanceArgs来创建一个新的类的实例,代码如下:
$reflection = new ReflectionClass('A');
$newclass = $reflection->newInstanceArgs([1,2,3]);
$newclass->test(1,2,3);
它的效果等同于:
$a = new A(1,2,3);
$a->test(1,2,3);
具体可以参见
首先定义一个类A,用ReflectionClass得到A的反射类对象,通过ReflectionClass对象可以得到类的各种属性,包括命名空间,父类,类名等,使用newInstanceArgs可以传入构造函数的参数创建一个新的类的实例。
class A
{
public $name;
public function __Construct($name,$des)
{
$this->name = $name.','.$des;
}
public function aa()
{
echo $this->name;
}
}
$class = new ReflectionClass('A');
$aaa = $class->newInstanceArgs(['www.111cn.net','blog']);
$aaa->aa();
输出结果:www.111cn.net,blog
以上示例中的$aaa即是通过newInstanceArgs创建的一个新的A类的实例,因此它可以调用A类的方法aa(),值得注意的是newInstanceArgs创建新类必须传参,也就是要求这个类要有构造方法。