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.netphp call_user_func_array函数有什么不好的地方吗?
php问题 call_user_func_array 这个函数什么时候用?最近再看tp框架 很多地方用到了这个函数
使用call_user_func_array()来回调执行函数与直接使用函数的区别是什么?
Benchmarking magic–PHP
相关文章推荐
- php的冷门函数之——call_user_func_array,func_get_args,func_num_args
- php的冷门函数之——call_user_func_array,func_get_args,func_num_args
- call_user_func_array,func_num_args,func_get_arg
- PHP的一些函数call_user_func_array,func_get_args()
- php 函数func_get_args()、func_get_arg()与func_num_args()之间的比较
- func_get_arg(), func_get_args() 和 func_num_args() 函数
- php函数之func_get_args()、func_get_arg()与func_num_args()
- 函数无限参数,func_num_args 和 func_get_arg 函数
- php 函数:func_get_args()、func_get_arg()与func_num_args()
- php 函数:func_get_args()、func_get_arg()与func_num_args()
- 无论url请求什么.都可以拼接class类名.实例化.传递get参数-->给当前控制器-->传递给抽象父类-->都交给抽象父类.这个方法去处理call_user_func_array()
- php 函数:func_get_args()、func_get_arg()与func_num_args()
- func_get_args() func_get_arg(offset) func_num_args(); 函数使用
- php 函数:func_get_args()、func_get_arg()与func_num_args()
- php函数call_user_func_arrray、call_user_func、func_get_args、func_num_args的用法
- php 函数:func_get_args()、func_get_arg()与func_num...
- php中几个操作函数参数的函数func_num_args() func_get_args() func_get_arg($i)php
- php函数之func_get_args()、func_get_arg()与func_num_args()
- php 函数func_get_args()、func_get_arg()与func_num_args()之间的比较
- PHP中func_get_args(),func_get_arg(),func_num_args()的区别