一、闭包基本用法
闭包(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. pyglet and opengl -- 纹理映射以及动画

    #-*- coding:gbk -*- #from pyglet.gl import * from OpenGL.GL import * import pyglet from pyglet impor ...

  2. Swift学习笔记5

    1.你可以将一个继承来的只读属性重写为一个读写属性,只需要在重写版本的属性里提供 getter 和 setter 即可.但是,你不可以将一个继承来的读写属性重写为一个只读属性. 2.你可以通过把方法, ...

  3. Linux 命令详解(八)Systemd 入门教程:实战篇

    Systemd 入门教程:实战篇 http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html

  4. VUE2.0 饿了吗视频学习笔记(二):新版本添加路由和显示Header

    https://gitee.com/1981633/vue_study.git 源码下载地址,随笔记动态更新中 webpack.dev.conf.js中添加两段代码 'use strict' cons ...

  5. luogu P1979 [NOIP2013] 华容道

    传送门 这道题中,棋子的移动是要移动到空格上去,所以空格要在棋子旁边才能移动棋子;而棋子移动的方向由空格决定 所以我们可以记三维状态\(di_{i,j,k}\),表示状态为棋子在\((i,j)\),空 ...

  6. 第18月第19天 masonry等分 uilabel sizetofit

    1.masonry等分 mas_distributeViewsAlongAxis MASAxisTypeHorizontal 2.uilabel sizetofit +(CGSize)labSizeW ...

  7. MHA-Failover(GTID,Auto_Position=0)

    最近一位同学遇到的案例:凌晨数据库意外宕机,要求在一主两从的基础上,搭建MHA做故障切换.在部署测试中遇到一些问题找到我,交流的过程挖出一些之前忽略的坑,感谢这位同学无私分享!• GTID环境,KIL ...

  8. D - Maximizing Advertising

    题目链接:https://cn.vjudge.net/contest/250168#problem/D 题目大意:给你一些点的坐标,这些点属于两个帮派,让你将这些点分进两个不能重叠的矩形中,问你最多两 ...

  9. python 面向对象的类

    参考<learn python hard way> 网址:https://learnpythonthehardway.org/book/ex41.html class X(Y) " ...

  10. Shiro后台实现验证权限

    今天发现一个问题:使用shiro的时候,虽然隐藏掉了一些菜单,但是当我们通过get请求直接访问菜单的时候还是会访问到,也就是shiro可以在界面实现隐藏一些信息,但是没有真正的根据权限码验证请求,于是 ...