回调、匿名函数和闭包

(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的值会随之改变。
时间: 2024-12-17 21:31:47

回调、匿名函数和闭包的相关文章

php中的匿名函数和闭包(closure)

一:匿名函数 (在php5.3.0 或以上才能使用) php中的匿名函数(Anonymous functions), 也叫闭包函数(closures), 允许指定一个没有名称的函数.最常用的就是回调函数的参数值.(http://php.net/manual/zh/functions.anonymous.php) 匿名函数的定义: $closureFunc = function(){ .... }; eg: 把匿名函数赋值给变量,通过变量来调用 $closureFunc = function($s

从匿名函数(闭包特性)到 PHP 设计模式之容器模式

匿名函数(匿名函数) 匿名函数,也叫闭包函数,它允许临时创建一个没有指定名称的函数,常用作回调函数参数的值,也可以作为变量的值来使用.具体的使用见以下示例代码: /* 示例一:声明一个简单匿名函数,并赋值给一个变量,通过变量名调用这个匿名函数 */ $anonFunc = function($param){ echo $param; }; $anonFunc('这里是一个匿名函数'); // 通过变量名调用匿名函数,和普通函数没什么区别 /* 示例二:通过在函数内部使用匿名函数动态创建函数 */

14.匿名函数和闭包

匿名函数和闭包 学习要点:1.匿名函数2.闭包 匿名函数就是没有名字的函数,闭包是可以访问一个函数作用域里变量的函数.声明:本节内容需要有面向对象和少量设计模式基础. 一.匿名函数 //普通函数function box(){ //函数名是box return 'Lee'; } //匿名函数function(){ //匿名函数,会报错,单独的匿名函数是无法运行的 return 'Lee';} //通过表达式自我执行(function box(){ //封装成表达式 alert('Lee');})(

匿名函数和闭包

匿名函数和闭包匿名函数就是没有名字的函数,闭包是可访问一个函数作用域里变量的函数.一. 匿名函数//普通函数functionbox() { //函数名是 boxreturn'Lee';}//匿名函数function() { //匿名函数,会报错return'Lee';}//通过表达式自我执行(function box() { //封装成表达式alert('Lee');})(); //()表示执行函数,并且传参//把匿名函数赋值给变量var box = function() { //将匿名函数赋给

javascript匿名函数与闭包

匿名函数是相对于有名字的函数 如function setAge(){}函数名为setAge 而类似于function(){}则就是一个匿名函数 有名字的函数执行时可以写成setAge(),而没有名字的函数则执行要写成(function())(); 另一种方式是把匿名函数赋值给一个变量来使用 var a=function(){ alert("hello,world"); } a(); 匿名函数传参 (function(age){ return age; })(100); 匿名函数产生闭包

匿名函数和闭包规避xdebug限制的函数递归深度限制

PHP版本5.6 先来个简单的用递归求和,代码如下: function add($n){     if($n === 1)return 1;     return add($n - 1); } echo add(256);  运行时报错: Maximum function nesting level of '256' reached, aborting! 这个报错的意思就是函数的递归深度最大是256,不能大于或等于256.在网上查找资料发现,这个是xdebug做的限制,可以通过更改配置文件来修改

Golang之匿名函数和闭包

Go语言支持匿名函数,即函数可以像普通变量一样被传递或使用. 使用方法如下: main.go package main import ( "fmt" ) func main() { var v func(a int) int v = func(a int) int { return a * a } fmt.Println(v(6)) //两种写法 v1 := func(i int) int { return i * i } fmt.Println(v1(7)) } GO语言的匿名函数就

GO 之匿名函数、闭包

匿名函数 go语言支持匿名函数,即像普通变量一样被引用或者传递 func main(){ var v func(a int) int v = func(a int) int { return a*a } fmt.Println(v(5)) //另一种写法 s := func(a int) int { return a*a } fmt.Println(s(7)) } GO语言的匿名函数就是闭包,<go语言编程>中对闭包的解释是: 基本概念闭包是:可以包含自由(未绑定到特定对象)变量的代码块,这些

内置函数补充、匿名函数及闭包

内置函数.匿名函数及闭包 匿名函数 def func(x,y): return (x,y) print(func(1,2)) # 结果: (1,2) f = lambda x,y:(x,y) # lambda关键字 print(f(1,2)) # 结果: (1,2) print((lambda x,y:(x,y))(1,2)) # 结果: (1,2) # 一行代码实现匿名函数的定义及调用 print(lambda :1) print((lambda :1)()) # 匿名函数可以不写参数,但必须

JavaScript匿名函数和闭包

概述 在JavaScript前端开发中,函数与对其状态即词法环境(lexical environment)的引用共同构成闭包(closure).也就是说,闭包可以让你从内部函数访问外部函数作用域.在JavaScript,函数在每次创建时生成闭包.匿名函数和闭包可以放在一起学习,可以加深理解.本文主要通过一些简单的小例子,简述匿名函数和闭包的常见用法,仅供学习分享使用,如有不足之处,还请指正. 普通函数 普通函数由fucntion关键字,函数名,() 和一对{} 组成,如下所示: 1 functi