<?php /** * 匿名函数与闭包学习 * * 首先是匿名函数 */ /* * 一个例子 * array_map * 定义一个函数 * array_map 回调这个函数 */ function addOne($args) { return $args + 1; } $data = array_map('addOne', array(1, 2, 3, 4)); print_r($data); /* * 变形 * 直接用闭包huo匿名函数做回调 * * 上面的做法把回调的实现和使用场所隔离开了, * 可见使用闭包实现代码更加简洁。 */ $data2 = array_map(function ($args) { return $args + 1; }, array(1, 2, 3, 4)); print_r($data2); /* * 闭包是一个对象,所以我们可以在闭包中使用$this关键字获取闭包的内部状态, * 闭包对象的默认状态没什么用,需要注意的是其中的__invoke魔术方法和bindTo方法。 */ $funName = function ($args) { return $args; }; echo "<br>", $funName(1), "<br>", $funName(2); class Test { public function __invoke() { return "对象用方法调用时默认的输出"; } public function testA($args) { return $args; } public function ha() { return 'hah'; } } $te = new Test(); echo $te(); //对象用方法调用时默认的输出 /* * 让匿名函数绑定对象测试 */ $testA = function () { $this->testA(); }; /* * 含有参数的匿名函数绑定对象 * */ $testCl = function ($funcname, $args) { return $this->$funcname($args); }; $aa = $testA->bindTo(new Test(), 'Test'); echo $aa('testa'); $cc = $testCl->bindTo(new Test(), 'Test'); echo '<br>' . $cc('ha', 1); //php7中的用法 echo $testCl('ha', 1)->call(new Test);
下面是有意思的闭包的例子,他返回的是函数,所以可以这样子。
<?php function operate($operator) { if ($operator == "-") { return function ($a, $b) { return $a - $b; }; } else { return function ($a, $b) { return $a + $b; }; } } $subtraction = operate("-"); echo $subtraction(4, 3);//1 $addition = operate("+"); echo $addition(1, 2);//3
<?php header("Content-Type:text/html;charset=utf-8"); class Di { private $_factory; public function set($id, $value) { $this->_factory[$id] = $value; } public function get($id) { $value = $this->_factory[$id]; return $value(); } } class User { private $_username; function __construct($username = "") { $this->_username = $username; } function getUserName() { return $this->_username; } } //从这里开始看 $di = new Di(); $di->set("zhangsan", function () { return new User('张三'); }); $di->set("lisi", function () { return new User("李四"); }); echo $di->get("zhangsan")->getUserName(); echo $di->get("lisi")->getUserName(); /* 代码中有一个Di容器用来保存对象实例,然后通过set()方法注册服务,通过get()方法获取服务。 我们看到$di->set()的时候,使用了匿名函数,我们预先注册了zhangsan和lisi两个服务,这两个服务都是User类的实例, 在$di->set的时候实际上并没有实例化,而是在$di->get()的时候才执行了匿名函数并将对象返回,这就实现了按需实例化, 不用则不实例化,提高效率。 经常写js的同学应该知道js的闭包特性,简单的说就是在一个函数里可以定义子函数,父函数中的变量在子函数中可以直接使用, 那么PHP的闭包怎么用呢?有一点区别。 */ function func1($a){ return function() use ($a){ echo $a; }; } $a = func1("a"); $a();//输出a /* 当你想将外层变量传进内层匿名函数时,使用use (变量)的方式。 闭包的用途可以用于很多地方,常见于DI模式中,这篇文章的代码只是为了说明,不可以直接使用,谢谢。 */