PHP 中的Closure

2017-02-24 16:53:58

PHP 中的Closure

Closure,匿名函数,又称为Anonymous functions,是php5.3的时候引入的。匿名函数就是没有定义名字的函数。这点牢牢记住就能理解匿名函数的定义了。

比如下面的代码

function test() {    return 100;
};function testClosure(Closure $callback)
{    return $callback();
}$a = testClosure(test());print_r($a);exit;

这里的test()永远没有办法用来作为testClosure的参数,因为它并不是“匿名”函数。

所以应该改成这样:

$f = function () {    return 100;
};function testClosure(Closure $callback){    return $callback();
}

$a = testClosure($f);
print_r($a);exit;

好,如果要调用一个类里面的匿名函数呢?

class C {    public static function testC() {        return function($i) {            return $i+100;
        };
    }
}

$f = function ($i) {    return $i + 100;
};function testClosure(Closure $callback){    return $callback(13);
}

$a = testClosure(C::testC());
print_r($a);exit;

应该这么写,其中的C::testC()返回的是一个funciton。

绑定的概念

上面的例子的Closure只是全局的的匿名函数,好了,我现在想指定一个类有一个匿名函数。也可以理解说,这个匿名函数的访问范围不再是全局的了,是一个类的访问范围。

那么我们就需要将“一个匿名函数绑定到一个类中”。

<?phpclass A {    public $base = 100;

}class B {    private $base = 1000;
}

$f = function () {    return $this->base + 3;
};


$a = Closure::bind($f, new A);
print_r($a());echo PHP_EOL;

$b = Closure::bind($f, new B , 'B');
print_r($b());echo PHP_EOL;

上面的例子中,ff这个匿名函数中莫名奇妙的有个this,这个this关键词就是说明这个匿名函数是需要绑定在类中的。

绑定之后,就好像A中有这么个函数一样,但是这个函数是public还是private,bind的最后一个参数就说明了这个函数的可调用范围。

对于bindTo,看例子:

<?phpclass A {    public $base = 100;

}class B {    private $base = 1000;
}class C {    private static $base = 10000;
}

$f = function () {    return $this->base + 3;
};

$sf = static function() {    return self::$base + 3;
};


$a = Closure::bind($f, new A);
print_r($a());echo PHP_EOL;

$b = Closure::bind($f, new B , 'B');
print_r($b());echo PHP_EOL;

$c = $sf->bindTo(null, 'C');
print_r($c());echo PHP_EOL;


  • 2018-04-18 15:56:00

    linux下如何实现mysql数据库每天自动备份定时备份

    备份是容灾的基础,是指为防止系统出现操作失误或系统故障导致数据丢失,而将全部或部分数据集合从应用主机的硬盘或阵列复制到其它的存储介质的过程。而对于一些网站、系统来说,数据库就是一切,所以做好数据库的备份是至关重要的!

  • 2018-04-18 20:44:19

    $(...).live is not a function

    jquery中的live()方法在jquery1.9及以上的版本中已被废弃了,如果使用,会抛出TypeError: $(...).live is not a function错误。

  • 2018-04-19 16:31:03

    mysql双机热备的实现

    准备两个mysql,A和B,A为主,B为从。前提是这两个数据库现在的表结构要一模一样,否则不成功。这个要锁表处理了。

  • 2018-04-19 16:32:47

    mysql binlog_do_db参数设置的坑

    在配置文件中想当然地配置成binlog_do_db=test,xx,jj,以为是三个库。结果无论什么操作都没有binlog产生

  • 2018-04-20 02:11:58

    Android中finish掉其它的Activity

    在Android开发时,一般情况下我们如果需要关掉当前Activity非常容易,只需要一行代码 this.finish;即可。 那么,如果是想要在当前Activity中关掉其它的Activity应该怎么实现呢? 比如更改了某个设定,程序需要重新运行并加载新的配置文件,就要用到restart或finish让程序重启。

  • 2018-04-20 09:12:07

    如何在 7 分钟内黑掉 40 家网站?

    去年夏天我开始学习信息安全与黑客技术。在过去的一年中,我通过参加各种战争游戏、夺旗以及渗透测试模拟,不断提高我的黑客技术,还学习了很多关于“如何让计算机偏离其预期行为”的新技术。

  • 2018-04-25 00:46:48

    Android开发笔记——SharedPreferences 存储实体类以及任意类型

    我们常常要用到保存数据,Android中常用的存储方式有SQLite,sharedPreferences 等,当然也有各自的应用场景,前者适用于保存较多数据的情形,后者责倾向于保存用户偏好设置比如某个checkbox的选择状态,用户登录的状态等等,都是以键值对的形式进行的文件读取,可以存储String,int,booean等一些基本数据类型等等。