现代 PHP 新特性 —— 闭包
一、概述
https://www.php.net/manual/zh/class.closure.php
闭包是指在创建时封装周围状态的函数,即使闭包所在的环境的不存在了,闭包中封装的状态依然存在。
闭包对象实现了__invoke()魔术方法,只要变量名后有(),PHP就会查找并调用__invoke方法。
1、闭包可以赋值给变量
2、闭包可以作为参数(回调函数)传递给函数
3、闭包可以作为函数的返回值
4、定义一个闭包函数,即产生了一个闭包类(Closure)的对象
Closure {
/* Methods */
private __construct ( void )
/**
* Closure::bindTo的静态版本
*/
public static bind ( Closure $closure , object $newthis [, mixed $newscope = "static" ] ) : Closure
/**
* 复制当前闭包对象,绑定指定的$this对象和类作用域。
*/
public bindTo ( object $newthis [, mixed $newscope = "static" ] ) : Closure
/**
* 绑定闭包对象到$newthis,并使用参数$parameters进行调用
*/
public call ( object $newthis [, mixed $... ] ) : mixed
/**
* 将一个callable对象转换成一个闭包对象
*/
public static fromCallable ( callable $callable ) : Closure
}
方法说明:
Closure::bind: 复制一个闭包,绑定指定的 $this 对象和类作用域。是 Closure::bindTo() 的静态版本。
Closure::bindTo: 复制当前闭包对象,绑定指定的 $this 对象和类作用域。
call()和fromCallable()是从PHP 7.0以后新增的。
bind参数和返回值说明:
closure:表示需要绑定的闭包对象。
newthis:表示需要绑定到闭包对象的对象,或者 NULL 创建未绑定的闭包。
newscope:表示想要绑定给闭包的类作用域,可以传入类名或类的示例,默认值是'static', 表示不改变。类作用域用来决定在闭包中 $this 对象的 私有、保护方法 的可见性。
该方法成功时返回一个新的 Closure 对象,失败时返回 FALSE。
bindTo参数和返回值说明:
newthis:表示需要绑定到闭包对象的对象,或者 NULL 创建未绑定的闭包。
newscope:表示想要绑定给闭包的类作用域,可以传入类名或类的示例,默认值是'static', 表示不改变。
使用:
Closure类的bindTo()和bind()方法提供了将一个闭包绑定到一个类对象的功能
<?php
class Animal {
private static $cat = "cat";
private $dog = "dog";
public $pig = "pig";
public function say(string $param)
{
return 'hello '. $param;
}
}
/*
* 获取Animal类静态私有成员属性
*/
$cat = static function() {
return Animal::$cat;
};
/*
* 获取Animal实例私有成员属性
*/
$dog = function() {
return $this->dog;
};
/*
* 获取Animal实例公有成员属性
*/
$pig = function() {
return $this->say($this->pig);
};
// 给闭包绑定了Animal实例的作用域,但未给闭包绑定$this对象,因此不能使用$this对象
$bindCat = Closure::bind($cat, null, new Animal());
// 给闭包绑定了Animal类的作用域,同时将Animal实例对象作为$this对象绑定给闭包,因此可以访问非公有的属性和方法
$bindDog = Closure::bind($dog, new Animal(), 'Animal');
// 将Animal实例对象作为$this对象绑定给闭包,保留闭包原有作用域,因此只能调用公有的属性和方法
$bindPig = Closure::bind($pig, new Animal());
// 根据绑定规则,允许闭包通过作用域限定操作符获取Animal类静态私有成员属性,若没有作用域,则只能访问公有的
echo $bindCat(),'<br>'; // cat
// 根据绑定规则,允许闭包通过绑定的$this对象(Animal实例对象)获取Animal实例所有的成员属性和方法
echo $bindDog(),'<br>'; // dog
// 根据绑定规则,允许闭包通过绑定的$this对象获取Animal实例公有成员属性和方法
echo $bindPig(),'<br>'; // hello pig
// bindTo与bind类似,bind是bindTo的静态版本,这里只举一个,其他类比就可以
$bindCat = $cat->bindTo(null, 'Animal');
echo $bindCat(); // cat
官方实例
<?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"; // 1
$cl = $cl->bindTo($ob2);
echo $cl(), "\n"; // 2
call 绑定闭包对象到$newthis,并使用参数$parameters进行调用
<?php
class Value {
protected $value; public function __construct($value) {
$this->value = $value;
} public function getValue() {
return $this->value;
}
} $three = new Value(3);
$four = new Value(4); $closure = function ($delta) { var_dump($this->getValue() + $delta); };
$closure->call($three, 4); //
$closure->call($four, 4); //
二、综合实例
<?php class A
{
public $a; public function __construct($a)
{
$this->a = $a;
} public function getValue()
{
return $this->a;
}
} function say($world = 'hello world!')
{
return $world;
} function say2()
{
return $this->getValue();
} $say3 = function () {
return $this->getValue();
}; $obj = new A('aaa'); // 转为闭包对象
$say1 = Closure::fromCallable('say');
$func1 = $say1->bindTo($obj);
echo $func1(), '<br>'; // hello world! // 将函数转为闭包
$say2 = Closure::fromCallable('say2');
$func2 = $say2->bindTo($obj);
echo $func2(), '<br>'; // aaa // 绑定闭包对象到$obj,并进行调用
echo $say3->call($obj),'<br>'; // aaa // 使用bind的静态版本
$func3 = Closure::bind($say3, $obj);
echo $func3(); // aaa
现代 PHP 新特性 —— 闭包的更多相关文章
- ES6 新特性
ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES2015. ...
- PHP的学习--新特性
最近做的项目使用了 php7,但感觉有很多新特性没有用起来.就想总结一下,一些可能会用到的新特性.之前使用的环境是 php5.4,所有也会有 php5.5 和 php5.6 的特性总结进来,这里只列出 ...
- Swift3新特性汇总
之前 Apple 在 WWDC 上已将 Swift 3 整合进了 Xcode 8 beta 中,而本月苹果发布了 Swift 3 的正式版.这也是自 2015 年底Apple开源Swift之后,首个发 ...
- Java 8新特性终极指南
目录结构 介绍 Java语言的新特性 2.1 Lambdas表达式与Functional接口 2.2 接口的默认与静态方法 2.3 方法引用 2.4 重复注解 2.5 更好的类型推测机制 2.6 扩展 ...
- php5.3到php7.0.x新特性介绍
<?php /*php5.3*/ echo '<hr>'; const MYTT = 'aaa'; #print_r(get_defined_constants()); /* 5.4 ...
- Java8的新特性以及与C#的比较
函数式接口 VS 委托 在C中,可以使用函数指针来存储函数的入口,从而使得函数可以像变量一样赋值.传递和存储,使得函数的调用变得十分灵活,是实现函数回调的基础.然而函数指针不存在函数的签名信息,甚至可 ...
- JAVA8 十大新特性详解
前言: Java8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章, 例如Playing with Java ...
- 简单理解ECMAScript2015中的箭头函数新特性
箭头函数(Arrow functions),是ECMAScript2015中新加的特性,它的产生,主要有以下两个原因:一是使得函数表达式(匿名函数)有更简洁的语法,二是它拥有词法作用域的this值,也 ...
- paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较
paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较 PHP5的新特性 2 · 对象的参照过渡是默认的(default) 3 · 引入访问属性的限制 3 · 引入访问方法的限 ...
随机推荐
- [PHP] 编写爬虫获取淘宝网上所有的商品分类以及关键属性 销售属性 非关键属性数据
参考文章地址:https://blog.csdn.net/zhengzizhi/article/details/80716608 http://open.taobao.com/apitools/api ...
- html5 css折叠导航栏
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- POSIX
API: POSIX (编译前的源代码) ABI: APPLICATION BINARY INTERFACE (编译后的二进制文件,linux & windows不兼容) ---------- ...
- 2018-2019-2 《网络对抗技术》Exp0 Kali安装 Week1 20165316
2018-2019-2 <网络对抗技术>Exp0 Kali安装 Week1 20165316 下载 我分别下载了kali-linux-2019.1-i386的镜像文件和kali-linux ...
- 记使用expo与expoKit分离工程遇到的坑
expoKit是支持expo平台的Objective-C和Java库,比纯RN一个个引入包开发效率会高一些,比如react-native-vector-icons包已经集成在expoKit中了. 假定 ...
- 面试官问我“Java中的锁有哪些?以及区别”,我跪了
在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏向锁/轻量级 ...
- PL/SQL执行计划查看
一.如何查看PLSQL的执行计划 在SQl Window窗口输入sql语句,然后按键"F5",就会进入执行计划查看界面. 二.界面说明 首先我们看第二行有几个属性可以选“Tree” ...
- hdfs性能调优(cloudera)
参照官方文档:http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/cdh_ig_yarn_tuni ...
- P4717 【模板】快速沃尔什变换
思路 FWT的模板 FWT解决这样的卷积 \[ C_k=\sum_{i\otimes j=k} A_iB_j \] \(\otimes\)可能是and,or,xor等位运算 几个式子 FWTand: ...
- 前端——BOM和DOM
要想和浏览器有交互的动作,即要继续学习DOM,BOM. JavaScript分为 ECMAScript,DOM,BOM. BOM (Browser Object Model) 是指浏览器对象模型,他使 ...