匿名函数

提到闭包就不得不想起匿名函数,也叫闭包函数(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. vue2.0 仿手机新闻站(三)通过 vuex 进行状态管理

    1.创建 store 结构 2.main.js  引入 vuex 3. App.vue  组件使用 vuex <template> <div id="app"&g ...

  2. 【Excle数据透视表】如何移动数据透视表的位置

    数据透视表创建完成了,现在需要将它移动到D5位置,如何移动呢? 解决办法 通过"移动数据透视表"功能实现数据透视表的位置移动 步骤1 单击数据透视表任意单元格→数据透视表工具→分析 ...

  3. tomcat启动出现异常 Error filterStart

    tomcat启动中出现 Error filterStart异常, 没有任何堆栈信息,如下: SEVERE: Error filterStart Jul 6, 2012 3:39:05 PM org.a ...

  4. 楼梯跳跃代码web

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  5. Javascript模式(一) 单例模式

    function A(){ // 存储实例对象 var instance; // 重写构造函数,只返回闭包内的局部变量instance A = function(){ return instance; ...

  6. 高阶函数:sorted

    排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的 ...

  7. Android 开发资源

    0x00 Android 入门资料 a. Android 学习之路 b.<第一行代码> 介绍及购买链接:http://blog.csdn.net/guolin_blog/article/d ...

  8. IE8 "开发人员工具" 无法使用,无法显示

    经常使用IE8开发工具的开发人员可能会遇到这么一种去情况:按F12时任务栏里出现开发人员工具的任务,但是开发人员工具窗体不弹出,也不出现在IE8里,重装IE88后还是存在此问题. 解决办法其实非常简单 ...

  9. Xenomai 3 POSIX

    Xenomai 3在架构设计上确实优先Xenomai 2,至少对开发者来说,少维护了不少东西,看下面两张图就知道了 第一张图是Xenomai2的,第二张图是Xenomai3的,Xenomai3在内核中 ...

  10. Docker入门系列4:命令行小结

    百度Baidu App Engine(BAE)平台也是以Docker作为其PaaS云基础. 目的就是为了解决以下问题: 1) 环境管理复杂: 从各种OS到各种中间件再到各种App,一款产品能够成功发布 ...