一、概述

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. Vuex 2.0 深入简出

    最近面试充斥了流行框架Vue的各种问题,其中Vuex的使用就相当有吸引力.下面我就将自己深入简出的心得记录如下: 1.在vue-init webpack project (创建vue项目) 2.src ...

  2. 阿里云 SSL 证书 总结

    历时2天左右的证书上传部署,终于结束了! 因为公司要开发小程序,小程序部署到开发环境必须支持https证书行. 阿里云目前的证书还是比较多的额,大致分为2类,一类是支持单域名,一类是支持泛域名. 自己 ...

  3. spring里的事物设置

    有的人说事物在spring里设置有两种,其实事物设置在spring配置文件中共有五种方式:第一种方式:每个Bean都有一个代理第二种方式:所有Bean共享一个代理基类第三种方式:使用拦截器第四种方式: ...

  4. DNS 本质

    DNS 本质: 层级分布式数据库

  5. ARMLCD屏调试2--ili9325驱动编写

    2011-06-24 21:57:09 一,读id--完成 二,自己写了驱动--完成 三,调试LCD屏驱动--完成 一         读id,不过过程还有点曲折. 因为之前写命令写数据的时序是根据i ...

  6. Linux中DDNS配置

    1.实验拓扑结构 图1 实验拓扑图 2.项目要求 通过系统的搭建,能够为Web Server动态更新DNS信息. 3.项目开展思路(思维导图) 图2 DDNS实验思维导图 4.实验步骤 (1) 基础网 ...

  7. log4j日志实现重复警告slf4j-jdk14和log4j-over-slf4j

    因为各种三方库依赖的log4j实现不同,所以可能会出现找到多个log4j实现的警告,但是不影响程序(logback是会影响的),如下: SLF4J: Class path contains multi ...

  8. 利用Android-FingerprintManager类实现指纹识别

    安卓指纹识别 利用FingerprintManager主类进行指纹识别. Github项目地址 在安卓6.0中新增了API,FingerprintManager类,它是Google提供的帮助访问指纹硬 ...

  9. es6中promise实现ajax的例子

    function getData(url){ var pro = new Promise(function(resolve,reject){ var xhr = null; try{ xhr = ne ...

  10. centos7 安装pgsql

    1.添加prm安装源(或者从官网下载) PostgreSQL官网地址:https://yum.postgresql.org/ yum install https://download.postgres ...