首页 > 代码库 > 回调、匿名函数和闭包
回调、匿名函数和闭包
(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] => 110 11 [1] => 212 13 [2] => 314 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] => 210 11 [1] => 312 13 [2] => 414 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的值会随之改变。
回调、匿名函数和闭包