PHP call_user_func的一些用法和注意点
版本:PHP 5.6.28
在call_user_func的调用中:
1.参数的传递过程,并不是引用传值。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 error_reporting(E_ERROR); // 此处不是E_ALL
2 $cur_value = 1;
3
4 function increment(&$var)
5 {
6 $var++;
7 }
8 echo 'Before value is :' .$cur_value. "\n";
9 call_user_func('increment',$cur_value);
10 echo 'After call call_user_func : ' .$cur_value. "\n";
在E_ALL的报告级别下,可以看到控制台的有此输出:
如果要引用传值,可以使用call_user_func_array ;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 call_user_func_array('increment',array(&$cur_value));
2. PHP版本不大于5.3.0时,对面向对象里面的关键字的解析有所增强。在此之前,使用双引号来来连接一个类和里面的一个方法,把之作为参数来作为回调函数的会,将会发出一个 E_STRICT的警告,因为这个传入的参数被视为静态方法。
3. 变量函数比call_user_func效率高点,在一下的情况可以考虑使用call_user_func:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?php 2 function say($content) 3 { 4 echo $content ."\n"; 5 } 6 $content = 'Hello the world!'; 7 $func = 'say'; 8 9 echo 'Say the classic word one thousands times!' ."\n"; 10 11 echo 'Called by the Variable Function' ."\n"; 12 $start = microtime(true); 13 for($i = 0;$i < 10000;$i++) 14 { 15 $func($content); 16 } 17 $end = microtime(true); 18 $time1 = $end - $start; 19 20 echo 'Called by the call_user_func function ' ."\n"; 21 $start = microtime(true); 22 for($i = 0;$i < 10000;$i++) 23 { 24 call_user_func($func,$content); 25 } 26 $end = microtime(true); 27 $time2 = $end - $start; 28 29 echo 'Variable Function Cost ' .$time1. ' microseconds!' ."\n"; 30 echo 'Function of call_user_func Cost ' .$time2. ' microsecond!' ."\n";
win10终端输出:
phpstorm的终端:
注意:此截图是在win10控制台直接输出的单词结果,多次运行之后,时间并没有相差很大,但是变量函数平均的情况下还是稍快。
我直接在IDE phpstorm的终端多次测试运行之后,发现相比在控制台的输出,运行时间两个减了将近一半,可能有优化输出。
4.调用类中的方法,如果是静态的方法,可以通过命名空间加方法命直接调用;如果是非静态的方法,可以先实例化一个对象,通过对象和方法命组成的数组作为参数被调用。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?php
2 namespace Test;
3
4 class Test
5 {
6 static public function greet()
7 {
8 echo 'Hello the world!' ."\n";
9 }
10
11 public function say()
12 {
13 echo 'Good morning, sir!' ."\n";
14 }
15 }
16
17 call_user_func(__NAMESPACE__ .'\Test::greet');
18 call_user_func(array(__NAMESPACE__ .'\Test','greet'));
19
20 $test = new Test();
21 call_user_func(array($test,'say'));
5. 在引用别人的代码时,可能会有函数名称冲突的可能。如果是递归函数,可能就要修改内部的函数代码。使用call_user_func可以避免修改内部的代码。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 function qwertyuiop($i=1) { 2 return($i==1?1:$i*call_user_func(__FUNCTION__,$i-1)); 3 }
不过,个人觉得可以用变量函数代替使用call_user_func函数,可以吗?
学习记录,方便复习