您的位置:首页 > 编程语言 > PHP开发

PHP函数处理 函数(1): call_user_func(_array)、func_get_arg(s)、func_num_args

2017-10-26 18:50 881 查看

函数简介

call_user_func_array

mixed call_user_func_array ( callable $callback , array $param_arr )

把第一个参数作为回调函数(callback)调用,把参数数组(param_arr)作为回调函数的的参数传入。param_arr 要被传入回调函数的数组,这个数组得是索引数组。参数可以引用传递。

call_user_func

mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $… ]] )

第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。

parameter 0个或以上的参数,被传入回调函数。传入call_user_func()的参数不能为引用传递。

func_get_args

array func_get_args ( void ) 获取函数参数列表的数组。

返回一个数组,其中每个元素都是目前用户自定义函数的参数列表的相应元素的副本。

func_num_args

int func_num_args ( void )

Gets the number of arguments passed to the function.

func_get_arg

mixed func_get_arg ( int $arg_num )

从用户自定义函数的参数列表中获取某个指定的参数。

arg_num 参数的偏移量。函数的参数是从0开始计数的。当 arg_num 比实际传入的参数的数目大或小于0的时候发出一个警告,返回 FALSE 。

应用

call_user_func_array

场景一:函数名是未知、函数的参数类型及个数也是未知的

场景二:用于函数回调,回调函数可能是一个普通函数(动态调用普通函数,类似可变函数),可能是类方法,也可能是静态方法。如果使用call_user_func_array,你就不用去判断方法的类型

可以调用静态方法

class mrClass {

function test() {
if (is_object($this)) {
// do something for instance method 实例调用
echo 'this is an instance call <br />' . "\n";
} else {
// do something different for procedural method
echo 'this is a procedure call <br />' . "\n";
}
}

static function testStatic() {
if (is_object($this)) {
// do something for instance method 实例调用
echo 'this is an instance call <br />' . "\n";
} else {
// do something different for procedural method
echo 'this is a procedure call <br />' . "\n";
}
}
}

$inst = new mrClass();
$inst->test();

//Strict standards: Non-static method mrClass::test() should not be called statically
mrClass::test();//静态调用,没有生成$this,输出$this为null,并报错。is_object(null)返回false

//Strict standards: Non-static method mrClass::test() should not be called statically
mrClass::testStatic();//静态调用,没有生成$this,输出$this为null,并报错

echo '<hr>';

//Notice: Undefined variable: this, $this报的错,而不是调用报的错
call_user_func_array(array('mrClass','testStatic'),[]);


可以引用

function increment(&$var)
{
$var++;
}

$a = 0;
//call_user_func('increment', &$a);//Fatal error: Call-time pass-by-reference has been removed in ...
call_user_func('increment', $a);//Warning: Parameter 1 to increment() expected to be a reference, value given in ...

echo $a."\n";

call_user_func_array('increment', array(&$a)); // You can use this instead before PHP 5.3
echo $a."\n";

//以上例程会输出:
//0
//1


func_num_args、func_get_arg

function foo()
{
$numargs = func_num_args();
echo "Number of arguments: $numargs<br />\n";
if ($numargs >= 2) {
echo "Second argument is: " . func_get_arg(1) . "<br />\n";
//var_dump(func_get_arg(-1)); //Warning: func_get_arg(): The argument number should be >= 0 in 。。。
//var_dump(func_get_arg(6)); //Warning: func_get_arg(): Argument 6 not passed to function in 。。。
}
$arg_list = func_get_args();
for ($i = 0; $i < $numargs; $i++) {
echo "Argument $i is: " . $arg_list[$i] . "<br />\n";
}
}

foo(1, 2, 3);

/*
以上例程会输出:
Number of arguments: 3<br />
Second argument is: 2<br />
Argument 0 is: 1<br />
Argument 1 is: 2<br />
Argument 2 is: 3<br />
*/


call_user_func与直接调用速度区别

在php中,使用“变量函数”(variiable function)会比call_user_func()慢,而call_user_func_array()比call_user_func()还要更慢。

相关的benchmark如下:

# Benchmark (2 million iterations)

# Operation                    Seconds
# Literal function          1.218
# Variable function         1.305
# call_user_func()          2.734
# call_user_func_array()    3.386


可以看到,变量函数和普通函数调用(literal function)速度差别不大,和call_user_func相差有一倍以上,而call_user_func_array则要更慢。所以你给的代码才会尽量避免使用call_user_func_array而更倾向于使用变量函数。因为只有很少的函数会有5个以上的参数,所以上面代码里才把1到5个函数的调用用变量函数来写,而只留下小部分的函数用call_user_func_array调用,从而最大的加快程序执行速度。

其实,这些函数的效率差异不会有想象的那么大,上面的benchmark是迭代200万次的结果,如果你的程序只会调用’call_user_func_array’几千次或以下,这些差异将会非常小(大概是0.002秒左右)。

参考

php.net

php call_user_func_array函数有什么不好的地方吗?

php问题 call_user_func_array 这个函数什么时候用?最近再看tp框架 很多地方用到了这个函数

使用call_user_func_array()来回调执行函数与直接使用函数的区别是什么?

Benchmarking magic–PHP
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  php 函数