一、概述

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 新特性 —— 闭包的更多相关文章

  1. ES6 新特性

    ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES2015. ...

  2. PHP的学习--新特性

    最近做的项目使用了 php7,但感觉有很多新特性没有用起来.就想总结一下,一些可能会用到的新特性.之前使用的环境是 php5.4,所有也会有 php5.5 和 php5.6 的特性总结进来,这里只列出 ...

  3. Swift3新特性汇总

    之前 Apple 在 WWDC 上已将 Swift 3 整合进了 Xcode 8 beta 中,而本月苹果发布了 Swift 3 的正式版.这也是自 2015 年底Apple开源Swift之后,首个发 ...

  4. Java 8新特性终极指南

    目录结构 介绍 Java语言的新特性 2.1 Lambdas表达式与Functional接口 2.2 接口的默认与静态方法 2.3 方法引用 2.4 重复注解 2.5 更好的类型推测机制 2.6 扩展 ...

  5. php5.3到php7.0.x新特性介绍

    <?php /*php5.3*/ echo '<hr>'; const MYTT = 'aaa'; #print_r(get_defined_constants()); /* 5.4 ...

  6. Java8的新特性以及与C#的比较

    函数式接口 VS 委托 在C中,可以使用函数指针来存储函数的入口,从而使得函数可以像变量一样赋值.传递和存储,使得函数的调用变得十分灵活,是实现函数回调的基础.然而函数指针不存在函数的签名信息,甚至可 ...

  7. JAVA8 十大新特性详解

    前言: Java8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章, 例如Playing with Java ...

  8. 简单理解ECMAScript2015中的箭头函数新特性

    箭头函数(Arrow functions),是ECMAScript2015中新加的特性,它的产生,主要有以下两个原因:一是使得函数表达式(匿名函数)有更简洁的语法,二是它拥有词法作用域的this值,也 ...

  9. 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 · 引入访问方法的限 ...

随机推荐

  1. Angular4 管道

  2. Fetch和ajax的比较和区别

    传统 Ajax 已死,Fetch 永生   Ajax 不会死,传统 Ajax 指的是 XMLHttpRequest(XHR),未来现在已被 Fetch 替代. 最近把阿里一个千万级 PV 的数据产品全 ...

  3. Keepalived配置文件详解

    global_defs { router_id LVS_$prio #节点唯一标识,通常为hostname } local_address_group laddr_g1 { ${lvs_node} # ...

  4. Flask实战-留言板-使用Bootstrap-Flask简化页面编写

    使用Bootstrap-Flask简化页面编写 扩展Bootstrap-Flask内置了可以快速渲染Bootstrap样式HTML组件的宏,并提供了内置的Bootstap资源,方便快速开发,使用它可以 ...

  5. Linux基础命令---iostat显示设备状态

    iostat iostat指令用来显示cpu状态,系统IO设备的状态,以及相关磁盘和NFS使用状态.iostat命令通过观察设备相对于其平均传输速率的活动时间来监视系统输入/输出设备负载.iostat ...

  6. php读取文件使用redis的pipeline(管道)导入大批量数据

    需求:需要做一个后台上传TXT文件,读取其中的内容,然后导入redis库中.要求速度快,并且支持至少10W以上的数据,而内容也就一个字段存类似openid和QQ 传统做法:我一开始做的时候就老套路,遍 ...

  7. for 循环,如果判断那里用到了一个函数,每次循环一次都会调用一次函数,如图

    但用高级for,可以不用每次都调用方法

  8. radhat6.6上安装oracle12c RAC (二)

    二.GI(Grid Infrastructure)安装 首先将安装包传到node1的目录 2.1 GI软件安装 2.1.1.解压安装包 #su - grid解压 GRID 到 GRID用户的$ORAC ...

  9. opencv学习之路(34)、SIFT特征匹配(二)

    一.特征匹配简介 二.暴力匹配 1.nth_element筛选 #include "opencv2/opencv.hpp" #include <opencv2/nonfree ...

  10. ORACLE中INSERT插入多条数据

    insert ALL into u_role_permission(rid,pid) values (4,12) into u_role_permission(rid,pid) values (3,4 ...