PHP 闭包(Closure)

2020-02-19 23:15:24

参考地址 PHP 闭包(Closure)


一、闭包基本用法

闭包(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



  • 2019-04-01 23:20:58

    隐藏在图片中的密钥

    在客户端开发的时候,有时需要把密钥保存在本地。这时就会遇到密钥安全性的问题。要保证密钥安全性,无非就是混淆、隐藏、白盒等手段。本文以隐藏在图片中来阐述密钥的安全保存。

  • 2019-04-01 23:22:33

    验证数字签名

    应预先设置验证首选项。在打开 PDF 后显示包含签名的验证详细信息时,这有助于确保数字签名有效。有关详细信息,请参阅设置签名验证首选项。

  • 2019-04-01 23:23:27

    图像隐写之使用PHP隐藏图像中的文本

    隐写术是一门研究隐藏信息的科学艺术,通过隐写术,可以只让发送者和接收者知道隐藏的信息。 图像隐写术则是研究将数据隐藏在图像中,通过该技术可以防止无关用户发现这些隐藏的信息或数据。

  • 2019-04-08 16:01:57

    Window 设置pm2开机自启动服务

    下面用 pm2 来启动我们自己的服务程序 app.js, 然后告诉 pm2 开机后自动运行我 app.js 继续在管理员命令行下, cd 到 app.js 所在目录

  • 2019-04-10 17:25:21

    Joda-Time详解,最好用的java时间工具

    任何企业应用程序都需要处理时间问题。应用程序需要知道当前的时间点和下一个时间点,有时它们还必须计算这两个 时间点之间的路径。使用 JDK 完成这项任务将非常痛苦和繁琐。