匿名函数

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

$func = function() {

}; //带结束符

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

$func = function( $param ) {
echo $param;
};
$func( 'some string' );
//输出:
//some string

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

实现闭包

//例一
//在函数里定义一个匿名函数,并且调用它
function printStr() {
$func = function( $str ) {
echo $str;
};
$func( 'some string' );
}
printStr(); //例二
//在函数中把匿名函数返回,并且调用它
function getPrintStrFunc() {
$func = function( $str ) {
echo $str;
};
return $func;
}
$printStrFunc = getPrintStrFunc();
$printStrFunc( 'some string' ); //例三
//把匿名函数当做参数传递,并且调用它
function callFunc( $func ) {
$func( 'some string' );
}
$printStrFunc = function( $str ) {
echo $str;
};
callFunc( $printStrFunc );
//也可以直接将匿名函数进行传递。如果你了解js,这种写法可能会很熟悉
callFunc( function( $str ) {
echo $str;
} );

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

function getMoney() {
$rmb = 1;
$dollar = 6;
$func = function() use ( $rmb ) {
echo $rmb;
echo $dollar;
};
$func();
}
getMoney();
//输出:
//1
//报错,找不到dorllar变量

可以看到,dollar没有在use关键字中声明,在这个匿名函数里也就不能获取到它,所以开发中要注意这个问题。

有人可能会想到,是否可以在匿名函数中改变上下文的变量,但我发现是不可以的:

function getMoney() {
$rmb = 1;
$func = function() use ( $rmb ) {
echo $rmb;
//把$rmb的值加1
$rmb++;
};
$func();
echo $rmb;
}
getMoney();
//输出:
//1
//1

啊,原来use所引用的也只不过是变量的一个副本而已。但是我想要完全引用变量,而不是复制。

要达到这种效果,其实在变量前加一个 & 符号就可以了:

function getMoney() {
$rmb = 1;
$func = function() use ( &$rmb ) {
echo $rmb;
//把$rmb的值加1
$rmb++;
};
$func();
echo $rmb;
}
getMoney();
//输出:
//1
//2

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

function getMoneyFunc() {
$rmb = 1;
$func = function() use ( &$rmb ) {
echo $rmb;
//把$rmb的值加1
$rmb++;
};
return $func;
}
$getMoney = getMoneyFunc();
$getMoney();
$getMoney();
$getMoney();
//输出:
//1
//2
//3

PHP闭包详解的更多相关文章

  1. Python闭包详解

    Python闭包详解 1 快速预览 以下是一段简单的闭包代码示例: def foo(): m=3 n=5 def bar(): a=4 return m+n+a return bar >> ...

  2. Swift 中的Closures(闭包)详解

    Swift 中的Closures(闭包)详解 在Swift没有发布之前,所有人使用OC语言编写Cocoa上的程序,而其中经常被人们讨论的其中之一 -- Block 一直备受大家的喜爱.在Swift中, ...

  3. PHP中的闭包详解

    PHP闭包(Closure)使用详解 作者: 字体:[增加 减小] 类型:转载 时间:2013-05-02我要评论 本篇文章介绍了,PHP闭包(Closure)的使用介绍,需要的朋友参考下   不知不 ...

  4. js闭包详解

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包的特性 闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数 ...

  5. JavaScript之作用域与闭包详解

    前言: JavaScript是一种应用非常广泛的语言,其也有一些自身特点和优势,本文重在讲述其作用域机制以及闭包,会从一些实例来探讨其机理. 作用域在JavaScript程序员日常使用中有不同的含义, ...

  6. JS重点特性——闭包详解

    闭包特性:可以让定义好的函数作用域在调用时发生改变,具体说,调用运行时,可以让(定义时)作用域外其他函数访问到本函数的局部变量甚至参数.举例代码如下: <!DOCTYPE html> &l ...

  7. JavaScript 闭包详解

    一.Javascript闭包的用途 事实上,通过使用闭包,我们可以做很多事情.比如模拟面向对象的代码风格:更优雅,更简洁的表达出代码:在某些方面提升代码的执行效率. 1.匿名自执行函数 我们知道所有的 ...

  8. js 闭包 详解

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包的特性 闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数 ...

  9. javascript闭包详解

    以前写过一篇关于javascript闭包的随笔,javascript闭包,但是写的不够详细,也没有体现出闭包的强大之处.故作此篇. 众所周知,javascript没有块级作用域,只有函数作用域.那就意 ...

  10. JavaScript的闭包详解

    (1)定义: 函数内部返回一个函数,返回出来的这个函数叫做被我们称之为闭包(个人理解的最简单的表现形式,) (2)为什么要使用闭包呢? 局部变量在函数执行完之后就会被GC回收,有时候我们想在外部访问内 ...

随机推荐

  1. Odoo11 重大改变

    Table of Contents 新特性 Activity 项目子任务 组织架构 地址 域 widget 功能重构 Quant 份 procurement 补货 自动动作 动作绑定 去掉了stock ...

  2. js:argument

    引用:http://www.cnblogs.com/lwbqqyumidi/archive/2012/12/03/2799833.html    http://www.cnblogs.com/Fskj ...

  3. Nginx https免费SSL证书配置指南

    生成证书 $ cd /usr/local/nginx/conf $ openssl genrsa -des3 -out server.key 1024 $ openssl req -new -key  ...

  4. Google论文BigTable拜读

    这周少打点dota2,争取把这篇论文读懂并呈现出来,和大家一起分享. 先把论文搞懂,然后再看下和论文搭界的知识,比如hbase,Chubby和Paxos算法. Bigtable: A Distribu ...

  5. Eclipse工程前面有个红色的感叹号的解决办法

    今天从SVN下载下工程之后,编译完,发现有两个工程有个红色的感叹号,一直没找到什么原因,问百度老师,发现问题的解决办法了. 1.先在控制台上点击Problems 如果控制台没有Problems,点击工 ...

  6. EF获取DbContext中已注册的所有实体类型

    /// <summary> /// 获取DbContext中已注册的实体类型 /// </summary> /// <typeparam name="T&quo ...

  7. Hibernate连接池设置

    在公司第一次做项目放到服务器上测试,发现每隔一段时间不用数据库就连接不上了(以前学过连接池,很久没用就忘了),在myeclipse上的时候没发现,网上搜索才发现是hibernate连接池配置问题. 1 ...

  8. HTML 学习笔记 JQuery(animation)

    动画效果也是JQuery库吸引人的地方,通过JQuery的动画方法,能够轻松的为网页天假非常紧菜的视觉效果. show()方法和hide()方法 show()方法和hide()方法是JQuery中最基 ...

  9. 我的Android进阶之旅------>Android中MediaButtonReceiver广播监听器的机制分析

    今天看公司的一段关于MediaButtonReceiver的代码看的比较混乱,幸好看了下面的这篇文章,才能茅塞顿开的理解好代码.在此转载下来,以备以后理解,希望都到这篇文章的人也能够有所帮助. 本文转 ...

  10. python数据分析之:数据清理,转换,合并,重塑(二)

    一:移除重复数据 DataFrame经常出现重复行,就像下面的这样 In [7]: data=DataFrame({'k1':['one']*3+['two']*4,'k2':[1,1,2,3,3,4 ...