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-30 11:42:24

    php7+laravel+coreseek(sphinx)中文搜索初步实现(Linux)

    官网www.coreseek.cn已不能下载,所以需从网上找资源, 注意的一点是,笔者安装coreseek-3.2.14版本后,使用时提示client版本高于server版本的错误, php的sphinx扩展,为使用者,为client;coreseek是系统服务,为server

  • 2019-04-30 13:55:13

    浅谈mysql fulltext全文索引优缺点

    为什么会注意到mysql的fulltext? nima, 还是上次innodb转成tokudb引擎的事,这次alter修改表引擎的时候,提示percona tokudb是不支持fulltext索引的.

  • 2019-04-30 18:56:52

    elasticsearch文档操作

    使用了Elasticsearch提供的一整套强大的REST API,本文继续来看通过这一套API如何完成文档的基本操作。

  • 2019-05-05 14:04:11

    PHP使用CURL模拟POST/GET/PUT/DELETE方式提交数据

    最近因为工作需要,调用网盘接口来上传文件,我用了CURL库, 当然在用CURL库之前必须要在php中启用 cURL 设置 可以通过使用php_info()函数来得到cURL信息,如果看不到cURL信息的话,那么需要设置PHP并开启这个库。在Windows平台下,需要改一改php.ini文件的设置,找到 php_curl.dll,并取消前面的分号注释就行了。

  • 2019-05-07 00:04:04

    Tcpdf不使用css来实现线上合同和签章,图片悬浮

    以前虽然有了解过Tcpdf的用法,但是没有实际的应用过,最近在用tcpdf的时候发现对css支持很有限,使的如果想实现类似html的种种效果都很难,而我这次要做的就是 图片悬浮在文字上方形成类似水印或者盖章的效果。