回调匿名函数和闭包

Posted 勾践

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了回调匿名函数和闭包相关的知识,希望对你有一定的参考价值。

(1) is_callable用来检测传进来的值能被call_user_func或者array_walk等函数使用,它非常智能,能够测试数组,数组形式的有效回调应该是以对象作为第一个元素,以方法名作为第二个元素,类似 array(‘new SomeClass()‘, ‘someFunc‘)。

下面用例子来说明:

 1 function a(){
 2 
 3 }
 4 
 5 $a = ‘a‘;
 6 
 7 if(is_callable($a)){
 8 
 9     echo ‘a is callable <br>‘;
10 
11 } else {
12 
13     echo ‘a is not callable <br>‘;
14 
15 }

输出:

1 a is callable 
 1 class B{
 2 
 3     public function add($arg = []){
 4 
 5         echo ‘sum: ‘ . ($arg[0] + $arg[1]) . ‘<br>‘;
 6 
 7     }
 8 
 9 }
10 
11 $c = [new B(), ‘add‘];
12 
13 if(is_callable($c)){
14 
15     call_user_func($c, [1, 2]);
16 
17 }

输出:

1 sum: 3

(2) array_walk 将用户自定义函数应用到数组中的每一个元素。

例子:

 1 $array = [1, 2, 3];
 2 
 3 function show($v, $k, $u){
 4 
 5     $v += 1;
 6 
 7     echo "u: {$u}, k: {$k}, v: {$v}<br>";
 8 
 9 }
10 
11 array_walk($array, ‘show‘, ‘Jerry‘);
12 
13 echo ‘<pre>‘;
14 
15 print_r($array);

在这个例子中,需要注意,array_walk函数第一个参数为数组名,第二个参数为回调函数名,第三个为用户自定义参数,在本例中,show函数的第一个参数为数组$array的值,第二个参数为数组$array的键值或者索引,第三个参数为用户自定义参数,对应着array_walk的第三个参数,本例输出如下:

 1 u: Jerry, k: 0, v: 2
 2 u: Jerry, k: 1, v: 3
 3 u: Jerry, k: 2, v: 4
 4 
 5 Array
 6 
 7 (
 8 
 9     [0] => 1
10 
11     [1] => 2
12 
13     [2] => 3
14 
15 )

如果想在show函数处理完之后同时改变原数组$array的值,可以在show函数的第一个参数前使用&引用地址符,示例如下:

 1 $array = [1, 2, 3];
 2 
 3 function show(&$v, $k, $u){
 4 
 5     $v += 1;
 6 
 7     echo "u: {$u}, k: {$k}, v: {$v}<br>";
 8 
 9 }
10 
11 array_walk($array, ‘show‘, ‘Jerry‘);
12 
13 echo ‘<pre>‘;
14 
15 print_r($array);

通过改变$v的值,同时改变数组$array的值,输出:

 1 u: Jerry, k: 0, v: 2
 2 u: Jerry, k: 1, v: 3
 3 u: Jerry, k: 2, v: 4
 4 
 5 Array
 6 
 7 (
 8 
 9     [0] => 2
10 
11     [1] => 3
12 
13     [2] => 4
14 
15 )

(3) call_user_func将其第一个参数作为回调函数使用,其余参数当做该回调函数的参数。

 1 function d($a, $b, $c){
 2 
 3     echo "a: {$a}, b: {$b}, c: {$c}<br>";
 4 
 5 }
 6 
 7 $f = ‘d‘;
 8 
 9 if(is_callable($f) && function_exists($f)){
10 
11     call_user_func($f, ‘Kue‘, ‘Sub‘, ‘Dod‘);
12 
13 }

输出:

1 a: Kue, b: Sub, c: Dod

(4) create_function创建匿名函数,第一个参数为该匿名函数的参数,第二个参数为匿名函数的函数体。

1 $n = create_function(‘$a, $b‘, ‘return $a + $b;‘);
2 
3 echo $n(1,2).‘<br>‘;

输出:3

其中,这个例子需要注意的地方是,第二个参数语句完成之后不要忘记加分号,如果不加会报错,错误信息如下:

1 Parse error:  syntax error, unexpected ‘}‘, expecting ‘;‘ in : runtime-created function on line 1

(5) 在php5.3以后,有更好的方式来实现create_function的功能,这就是内联函数的使用。

1 $e = function($arg){
2 
3     echo "arg: {$arg}<br>";
4 
5 };
6 
7 $e(‘Hello world!‘);

这是内联函数的基本用法,其中函数体结束需要以分号结束,本例会输出:

1 arg: Hello world!

(6) 闭包 use

 1 function message($m){
 2 
 3     $close = ‘door‘;
 4 
 5     $h = function($m) use(&$close, $m){
 6 
 7         echo "{$m} close the {$close} please!<br>";
 8 
 9         $close = ‘nali‘;
10 
11     };
12 
13     $h(‘Lily‘);
14 
15     echo $close.‘<br>‘;
16 
17 }
18 
19 echo call_user_func(‘message‘, ‘Jim‘);

输出:

1 Jim close the door please!
2 
3 nali
本例中 use 关键字将变量$close与内联函数$h连接在一起,如果$close前面不加&地址符,则$close的值不会改变,加上&之后,$close的值会随之改变。

以上是关于回调匿名函数和闭包的主要内容,如果未能解决你的问题,请参考以下文章

php的闭包

php值callback类型和匿名函数(闭包)

PHP匿名函数和闭包

PHP中的闭包和匿名函数

好好学python·函数进阶(递归函数,回调函数,闭包函数,匿名函数,迭代器)

PHP函数-匿名函数(闭包函数)