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-09-08 09:05:54

    MyBatis Generator 插件的拓展插件包

    应该说使用Mybatis就一定离不开MyBatis Generator这款代码生成插件,而这款插件自身还提供了插件拓展功能用于强化插件本身,官方已经提供了一些拓展插件,本项目的目的也是通过该插件机制来强化Mybatis Generator本身,方便和减少我们平时的代码开发量。

  • 2019-09-08 09:09:48

    mybatis-generator自动生成代码插件使用详解

      mybatis-generator是一款在使用mybatis框架时,自动生成model,dao和mapper的工具,很大程度上减少了业务开发人员的手动编码时间,今天自己研究了一下,也分享一下使用心得供大家简单使用。

  • 2019-09-08 15:09:14

    IDEA从mapper.java跳转到mapper.xml

    在IDEA中写项目后台的时候,从controller到service到mapper到dao,都可以直接跳转,但是mapper.java到mapper.xml就需要自行寻找,为了开发方便,安装相应插件--mybais

  • 2019-09-08 21:44:15

    git pre-commit hook failed 解决办法

    今天在上传项目的时候在commit阶段遇到一个问题,无论是在Sourcetree上传还是用命令git commit -m 'xxx'都报了一下错误:

  • 2019-09-08 21:45:31

    git index.lock

    因是在你进行某些比较费时的git操作时自动生成,操作结束后自动删除,相当于一个锁定文件,目的在于防止对一个目录同时进行多个操作。 有时强制关闭进行中的git操作,这个文件没有被自动删除,之后你就无法进行其他操作,必须手动删除,进入.git文件中删除,打开显示隐藏文件。如果没有看见.git文件夹,可以直接用命令rm -f ./.git/index.lock。之后就可以正常使用。 ———————————————— 版权声明:本文为CSDN博主「李瑞豪」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_39520417/article/details/81941111

  • 2019-09-09 05:28:54

    IntelliJ IDEA 进阶教程: 语言注入

    我真的太久没发 IntelliJ 的教程了,最近 Sakura 同学找我帮他配 IntelliJ ,我秀了一下技术,假装自己是老司机。 然后发现 Language Injection 这个非常好用的功能我居然没写教程(很明显,一堆人不知道这个东西), 于是我又开始写教程了。 本文多图。

  • 2019-09-09 05:32:55

    SrpingBoot 热启动与热部署

    当我们已经启动了一个服务,然后修改代码之后,会自动重新部署。Spring项目通常有新内容修改后需要重新编译然后运行。通过配置Spring boot的热启动配置,可以实现自动编译重启项目,通常要比手动停止,启动项目快。