mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
参数1:被调用的回调函数。
参数2-n:0个或以上的参数,被传入回调函数。
返回值:返回回调函数的返回值。
mixed call_user_func_array ( callable $callback , array $param_arr )
参数1: 被调用的回调函数。
参数2: 要被传入回调函数的数组,这个数组得是索引数组。
返回值:返回回调函数的结果。如果出错的话就返回 FALSE

比较这两者的不同哦。 后者的第二个参数必须是数组

1. 调用普通的函数

function barber($type)
{
    echo "You wanted a $type haircut, ok\n";
}
call_user_func('barber', "mushroom");    // You wanted a mushroom haircut, ok
call_user_func('barber', "shave");    // You wanted a shave haircut, ok
function barber($type)
{
    echo "You wanted a $type haircut, ok\n";
}
call_user_func_array('barber', array("mushroom"));    // You wanted a mushroom haircut, ok
call_user_func_array('barber', array("shave"));    // You wanted a shave haircut, ok

2. 调用类中的静态方法

namespace Foo;
class F {
    public static function showName ($name) {
        return strtoupper($name);
    }
}
echo call_user_func(__NAMESPACE__ . '\F::showName','vein');    // VEIN
echo call_user_func(array(__NAMESPACE__ . '\F','showName'),'vein');    // VEIN

$f = new F();
echo call_user_func(array($f, 'showName'),'vein');    // VEIN
namespace Foo;
class F {
    public static function showName ($name) {
        return strtoupper($name);
    }
}
echo call_user_func_array(__NAMESPACE__.'\F::showName', array('vein'));    // VEIN
echo call_user_func_array(array(__NAMESPACE__.'\F', 'showName'), array('vein'));    // VEIN
$f = new F();
echo call_user_func_array(array($f, 'showName'), array('vein'));    // VEIN

3. 动态方法调用

namespace Foo;
class F {
    public static function showName ($name) {
        return strtoupper($name);
    }

    public function showAge ($age) {
        return $age + 100;
    }
}
$f = new F();   // 非静态方法,请在实例化后作为参数传入,否则会报错
echo call_user_func(array($f, 'showAge'),23);
namespace Foo;
class F {
    public static function showName ($name) {
        return strtoupper($name);
    }

    public function showAge ($age) {
        return $age + 100;
    }
}
$f = new F();
echo call_user_func_array(array($f, 'showAge'),array(23));

4. 相关扩展

可以结合魔术方法 __call() 来实现简单的链式操作,比如对一个字符串先去掉两边空格,然后再计算字符长度。

示例代码:

class Str
{
    protected $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function __call($name, $args)
    {
        array_unshift($args, $this->value);
        $this->value = call_user_func_array($name, $args);
        return $this;
    }

    public function output()
    {
        echo $this->value;
    }
}

// 调用
$str = new Str('Hello World!');
$str->trim('Hed!')->strlen()->output(); //输出 8

5. 总结

call_user_funccall_user_func_array 两个函数基本上是类似的,只是在调用上传递参数时存在一些差异。

call_user_func 传递的第二个参数可以是数组。如果是多个参数的话,还是需要以列表的形式列出。

call_user_func_array 传递的第二个参数必须是索引数组。