一、闭包基本用法
闭包(Closure)又叫做匿名函数,也就是没有定义名字的函数。比如下面的例子:
// 定义一个闭包,并把它赋给变量 $f
$f = function () {
return 7;
} // 使用闭包也很简单
$f(); //这样就调用了闭包,输出 7 // 当然更多的时候是把闭包作为参数(回调函数)传递给函数
function testClosure (Closure $callback) {
return $callback();
} // $f 作为参数传递给函数 testClosure,如果是普遍函数是没有办法作为testClosure的参数的
testClosure($f); // 也可以直接将定义的闭包作为参数传递,而不用提前赋给变量
testClosure (function () {
return 7;
}); // 闭包不止可以做函数的参数,也可以作为函数的返回值
function getClosure () {
return function () { return 7; };
} $c = getClosure(); // 函数返回的闭包就复制给 $c 了
$c(); // 调用闭包,返回 7
二、闭包类(Closure)
定义一个闭包函数,其实是产生了一个闭包类(Closure)的对象,Closure类摘要如下:
Closure {
public static Closure bind (Closure $closure , object $newthis [, mixed $newscope = 'static' ])
public Closure bindTo (object $newthis [, mixed $newscope = 'static' ])
}
方法说明:
Closure::bind: 复制一个闭包,绑定指定的$this对象和类作用域。
Closure::bindTo: 复制当前闭包对象,绑定指定的$this对象和类作用域。
下面将介绍Closure::bind和Closure::bindTo
参数和返回值说明:
closure:表示需要绑定的闭包对象。
newthis:表示需要绑定到闭包对象的对象,或者NULL创建未绑定的闭包。
newscope:表示想要绑定给闭包的类作用域,可以传入类名或类的示例,默认值是 'static', 表示不改变。
该方法成功时返回一个新的 Closure 对象,失败时返回FALSE。
class Animal {
private static $cat = "cat";
private $dog = "dog";
public $pig = "pig";
} /*
* 获取Animal类静态私有成员属性
*/
$cat = static function() {
return Animal::$cat;
}; /*
* 获取Animal实例私有成员属性
*/
$dog = function() {
return $this->dog;
}; /*
* 获取Animal实例公有成员属性
*/
$pig = function() {
return $this->pig;
}; $bindCat = Closure::bind($cat, null, new Animal());// 给闭包绑定了Animal实例的作用域,但未给闭包绑定$this对象
$bindDog = Closure::bind($dog, new Animal(), 'Animal');// 给闭包绑定了Animal类的作用域,同时将Animal实例对象作为$this对象绑定给闭包
$bindPig = Closure::bind($pig, new Animal());// 将Animal实例对象作为$this对象绑定给闭包,保留闭包原有作用域
echo $bindCat(),'<br>';// 根据绑定规则,允许闭包通过作用域限定操作符获取Animal类静态私有成员属性
echo $bindDog(),'<br>';// 根据绑定规则,允许闭包通过绑定的$this对象(Animal实例对象)获取Animal实例私有成员属性
echo $bindPig(),'<br>';// 根据绑定规则,允许闭包通过绑定的$this对象获取Animal实例公有成员属性 // bindTo与bind类似,是面向对象的调用方式,这里只举一个,其他类比就可以
$bindCat = $cat->bindTo(null, 'Animal');
最后举一个PHP官网给出的例子
class A {
function __construct($val) {
$this->val = $val;
}
function getClosure() {
//returns closure bound to this object and scope
return function() { return $this->val; };
}
} $ob1 = new A(1);
$ob2 = new A(2); $cl = $ob1->getClosure();
echo $cl(), "\n";
$cl = $cl->bindTo($ob2);
echo $cl(), "\n";
以上示例输出:
1
2
 
 
 

PHP 闭包的更多相关文章

  1. 《Web 前端面试指南》1、JavaScript 闭包深入浅出

    闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...

  2. 干货分享:让你分分钟学会 JS 闭包

    闭包,是 Javascript 比较重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述 ...

  3. 深入浅出JavaScript之闭包(Closure)

    闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...

  4. javascript之闭包理解以及应用场景

    半个月没写博文了,最近一直在弄小程序,感觉也没啥好写的. 之前读了js权威指南,也写了篇博文,但是实话实说当初看闭包确实还是一头雾水.现在时隔一个多月(当然这一段时间还是一直有在看闭包的相关知识)理解 ...

  5. js闭包 和 prototype

    function test(){ var p=200; function q(){ return p++; } return q; } var s = test(); alert(s()); aler ...

  6. js闭包for循环总是只执行最后一个值得解决方法

    <style> li{ list-style: none;width:40px;height: 40px;text-align:center;line-height: 40px;curso ...

  7. JavaScript学习笔记(二)——闭包、IIFE、apply、函数与对象

    一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...

  8. 带你一分钟理解闭包--js面向对象编程

    上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...

  9. 如何设计一门语言(七)——闭包、lambda和interface

    人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...

  10. JavaScript 闭包深入浅出

    闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...

随机推荐

  1. java集合复制和反转

    1.for循环方法: 2.System.arraycopy()方法: 3.Arrays.copyOf()方法: 4.Object.clone()方法: + View code /** * @autho ...

  2. P2885 [USACO07NOV]电话线Telephone Wire

    P2885 [USACO07NOV]电话线Telephone Wire 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话 ...

  3. myeclipse 怎么安装与激活

    摘录自:http://blog.csdn.net/u012318074/article/details/71310553 第一步:安装完成后不要运行MyEclipse 第二步:下载对应的破解文件 第三 ...

  4. 修改tomcat启动窗口的名称

    场景:我们在启动tomcat的时候,一般会出现tomcat窗口,默认窗口名字是tomcat,如果我们想知道这个tomcat的端口号,我们需要查看配置文件,很麻烦有木有.如果我们可以直接把端口号设置在窗 ...

  5. Nginx 学习笔记(三)proxy_cache 缓存配置和ngx_cache_purge模块

    反向代理的缓存清理 一.proxy_cache配置 (1)如何配置和安装,都在这里了:https://github.com/Tinywan/Lua-Nginx-Redis/blob/master/Ng ...

  6. Redis模块学习笔记(一)RediSearch简单使用

    说明:安装的Redis服务器必须为 4.0 以上版本,通过info命令查看 > INFO redis_version: 一.安装 RediSearch git clone https://git ...

  7. wireshark数据包分析

    最近有不少同事开始学习Wireshark,他们遇到的第一个困难就是理解不了主界面上的提示信息,于是跑来问我.问的人多了,我也总结成一篇文章,希望对大家有所帮助.Wireshark的提示可是其最有价值之 ...

  8. jsp中的JSTL与EL表达式用法

    JSTL (JSP Standard Tag Library ,JSP标准标签库) JSTL标签库分为5类:JSTL核心标签库.JSTL函数标签库.数据库标签库.I18N格式化标签库.XML标签库. ...

  9. zabbix 在图形中显示网络设备的接口描述

    zabbix原始模板没有提供来显示网络设备接口的描述,我们通常看到的图形显示是下面这样的: zabbix 3之后图形显示变化蛮大的,但我们乍一看,并不知道这个ethernet0/1是什么接口,网络设备 ...

  10. Android 常用 adb 命令总结【转】

    原文链接 针对移动端 Android 的测试, adb 命令是很重要的一个点,必须将常用的 adb 命令熟记于心, 将会为 Android 测试带来很大的方便,其中很多命令将会用于自动化测试的脚本当中 ...