PHP之闭包详解

匿名函数
提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它。声明一个匿名函数是这样:

1 $func = function() {
2
3 }; //带结束符

可以看到,匿名函数因为没有名字,如果要使用它,需要将其返回给一个变量。匿名函数也像普通函数一样可以声明参数,调用方法也相同:

1 $func = function( $param ) {
2     echo $param;
3 };$func( ‘some string‘ );
4 //输出:
5 //some string

顺便提一下,PHP在引入闭包之前,也有一个可以创建匿名函数的函数:create function,但是代码逻辑只能写成字符串,这样看起来很晦涩并且不好维护,所以很少有人用。

实现闭包
将匿名函数在普通函数中当做参数传入,也可以被返回。这就实现了一个简单的闭包。

下边有三个例子

 1 //例一
 2 //在函数里定义一个匿名函数,并且调用它
 3 function printStr() {
 4     $func = function( $str ) {
 5         echo $str;
 6     };
 7     $func( ‘some string‘ );
 8 }printStr();
 9
10 //例二
11 //在函数中把匿名函数返回,并且调用它
12 function getPrintStrFunc() {
13     $func = function( $str ) {
14         echo $str;
15     };
16     return $func;
17 }
18 $printStrFunc = getPrintStrFunc();
19 $printStrFunc( ‘some string‘ );
20
21
22 //例三
23 //把匿名函数当做参数传递,并且调用它
24 function callFunc( $func ) {
25     $func( ‘some string‘ );
26 }
27 $printStrFunc = function( $str ) {
28     echo $str;
29 };
30 callFunc( $printStrFunc );
31 //也可以直接将匿名函数进行传递。如果你了解js,这种写法可能会很熟悉
32 callFunc( function( $str ) {
33     echo $str;
34 } );

连接闭包和外界变量的关键字:USE

 1 function getMoney() {
 2     $rmb = 1;
 3     $dollar = 6;
 4     $func = function() use ( $rmb ) {
 5         echo $rmb;
 6         echo $dollar;
 7     };
 8     $func();
 9 }getMoney();
10 //输出:
11 //1
12 //报错,找不到dorllar变量

闭包可以保存所在代码块上下文的一些变量和值。PHP在默认情况下,匿名函数不能调用所在代码块的上下文变量,而需要通过使用use关键字。 换一个例子看看:

可以看到,dollar没有在use关键字中声明,在这个匿名函数里也就不能获取到它,所以开发中要注意这个问题。
  有人可能会想到,是否可以在匿名函数中改变上下文的变量,但我发现是不可以的:

 1 function getMoney() {
 2     $rmb = 1;
 3     $func = function() use ( $rmb ) {
 4         echo $rmb;
 5         //把$rmb的值加1
 6         $rmb++;
 7     };
 8     $func();
 9     echo $rmb;
10 }getMoney();
11 //输出:
12 //1
13 //1

啊,原来use所引用的也只不过是变量的一个副本而已。但是我想要完全引用变量,而不是复制。 要达到这种效果,其实在变量前加一个 & 符号就可以了:

 1 function getMoney() {
 2     $rmb = 1;
 3     $func = function() use ( &$rmb ) {
 4         echo $rmb;
 5         //把$rmb的值加1
 6         $rmb++;
 7     };
 8     $func();
 9     echo $rmb;
10 }getMoney();
11 //输出:
12 //1
13 //2

好,这样匿名函数就可以引用上下文的变量了。如果将匿名函数返回给外界,匿名函数会保存use所引用的变量,而外界则不能得到这些变量,这样形成‘闭包‘这个概念可能会更清晰一些。

 1 function getMoneyFunc() {
 2     $rmb = 1;
 3     $func = function() use ( &$rmb ) {
 4         echo $rmb;
 5         //把$rmb的值加1
 6         $rmb++;
 7     };
 8     return $func;
 9 }$getMoney = getMoneyFunc();
10 $getMoney();
11 $getMoney();
12 $getMoney();
13 //输出:
14 //1
15 //2
16 //3

总结
PHP闭包的特性并没有太大惊喜,其实用CLASS就可以实现类似甚至强大得多的功能,更不能和js的闭包相提并论,只能期待PHP以后对闭 包支持的改进。不过匿名函数还是挺有用的,比如在使用preg_replace_callback等之类的函数可以不用在外部声明回调函数了。

本文链接地址:http://www.zhaoyafei.cn//index.php/home/article/articleinfo.html?id=21

本文属于转载,真诚推荐http://www.zhaoyafei.cn(赵亚飞)的个人博客网站,写的真的非常不错,真诚推荐!

时间: 2024-11-05 22:05:07

PHP之闭包详解的相关文章

Swift 中的Closures(闭包)详解

Swift 中的Closures(闭包)详解 在Swift没有发布之前,所有人使用OC语言编写Cocoa上的程序,而其中经常被人们讨论的其中之一 -- Block 一直备受大家的喜爱.在Swift中,同样有这样的一个角色,用于当开发者需要异步执行的之后使用的一种语法 - Closure.中文翻译为闭包. 闭包出了可以进行异步执行之外,它的完整使用还依赖闭包本身的变量.常量的捕获.闭包捕获并存储对它们定义的上下文中的任何常量和变量的引用,这也就意味着,你可以在任何时候异步执行闭包的时候获取之前的所

PHP中的闭包详解

PHP闭包(Closure)使用详解 作者: 字体:[增加 减小] 类型:转载 时间:2013-05-02我要评论 本篇文章介绍了,PHP闭包(Closure)的使用介绍,需要的朋友参考下 不知不觉发现PHP已经出到了5.5版本,而自己一直在用PHP5.2,让我看起来像深山出来的小伙子一样,又土又落后.在我习惯在javascript中使用闭包之后,忽然间对PHP的闭包打起了兴趣. 于是乎在网上下了个WAMP集成开发环境,是PHP5.3版本的(PHP5.3开始引入了闭包的特性),不得不说WAMP安

javascript闭包详解(内容为转载的,觉得不错就分享一下)

一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function f1(){ var n=999; } alert(n); // error 这里有一个地方需要注意,函数

JavaScript的闭包详解

(1)定义: 函数内部返回一个函数,返回出来的这个函数叫做被我们称之为闭包(个人理解的最简单的表现形式,) (2)为什么要使用闭包呢? 局部变量在函数执行完之后就会被GC回收,有时候我们想在外部访问内部的变量,这个时候就用到了闭包 (3)闭包有两个作用: a.访问函数内部的变量(函数作为返回值) b.保存作用域(函数作为参数传递) 1 //1.访问函数内部的变量(函数作为返回值) 2 function test(){ 3 var age = 18; 4 return function(){ 5

javascript系列2 -- 闭包详解

转发请标明来源:http://www.cnblogs.com/johnhou/p/javascript.html  请尊重笔者的劳动成果  --John Hou 今天我们从内存结构上来讲解下 javascript中的闭包概念. 闭包:是指有权访问另外一个函数作用域中的变量的函数.创建闭包的常见方式就是在一个函数内部创建另外一个函数. 在javascript中没有块级作用域,一般为了给某个函数申明一些只有该函数才能使用的局部变量时,我们就会用到闭包,这样我们可以很大程度上减少全局作用域中的变量,净

javascript函数及闭包详解

1.arguments[]对象在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们.还可以用 arguments 对象检测函数的参数个数,引用属性 arguments.length 2function对象的length属性ECMAScript 定义的属性 length 声明了函数期望的参数个数 3Function 对象也有与所有对象共享的 valueOf() 方法和 toString() 方法.这两个方法返回的都是函数的源代码,在调试时尤其有用 4闭包: 什么时

javascript--函数参数与闭包--详解

在看此课程的读者,希望先阅读关于函数基础内容 函数定义与函数作用域 的章节,因为此课程或多或少会涉及函数基础的内容,而基础内容,本人放在函数定义函数作用域 章节. 本文直接赘述函数参数与闭包,若涉及相关知识,为了节省篇章,会以相关字眼带过. 最近在学习javascript的函数,函数是javascript的一等对象,想要学好javascript,就必须深刻理解函数.本人把学习的过程整理成文章,一是为了加深自己函数的理解,二是给读者提供学习的途径,避免走弯路.内容有些多,但都是笔者对于函数的总结.

js闭包详解-转自好友trigkit4

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包的特性 闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变量不会被垃圾回收机制回收 闭包的定义及其优缺点 闭包 是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量 闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露. 闭包是javascript语言的一

JS重点特性——闭包详解

闭包特性:可以让定义好的函数作用域在调用时发生改变,具体说,调用运行时,可以让(定义时)作用域外其他函数访问到本函数的局部变量甚至参数.举例代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <scrip