PHP新特性之闭包、匿名函数
来源:互联网 发布:程序员的修炼之道 pdf 编辑:程序博客网 时间:2024/05/17 06:44
闭包
闭包是什么?
1).闭包和匿名函数在PHP5.3中被引入。
2).闭包是指在创建时封装函数周围状态的函数,即使闭包所在的环境不存在了,闭包封装的状态依然存在,这一点和Javascript的闭包特性很相似。
3).匿名函数就是没有名称的函数,匿名函数可以赋值给变量,还可以像其他任何PHP对象一样传递。可以将匿名函数和闭包视作相同的概念。
4).需要注意的是闭包使用的语法和普通函数相同,但是他其实是伪装成函数的对象,是Closure类的实例。闭包和字符串或整数一样,是一等值类型。
创建闭包
$closure = function () { return sprintf('hello %s', $name);}echo $closure('Josh');
我们之所以可以调用$closure变量,是因为这个变量的值是一个闭包,而且闭包对象实现了__invoke()
魔术方法,只要后面跟着()
,PHP就会查找__invoke()
方法。这里简单解释下这个魔术方法:
class testClass{ public function __invoke { print "hello world"; }}$n = new testClass;$n();
PHP自从5.3版以来就新增了一个叫做__invoke()
的魔术方法,使用该方法就可以在创建实例后,直接调用对象。
何时使用?
我们通常把PHP闭包当做函数和方法的回调使用。很多PHP函数都会用到回调函数,例如array_map()
和preg_replace_callback()
。
$numbersPlusOne = array_map(function($number) { return $number + 1;}, [1, 2, 3]);
如何理解附加状态?
1).注意PHP闭包不会真的像JS一样自动封装应用的状态,在PHP中必须调用闭包对象的bindTo方法或者使用use关键字,把状态附加到PHP闭包上。来看一个例子
function enclosePerson($name){ return function ($doCommand) use ($name) { return sprintf('%s , %s', $name, $doCommand); } }//把字符串“Clay”封装在闭包中$clay = enclosePerson('Clay');//传入参数,调用闭包echo $clay('get me sweat tea!'); // Clay, get me sweat tea!
在这个例子中,函数enclosePerson()
有一个$name
参数,这个函数返回一个闭包对象,这个闭包封装了$name
参数,即便返回的对象跳出了enclosePerson()
函数的作用域,它也会记住$name
参数的值,因为$name
变量仍然在闭包中。
2).使用use关键字可以把多个关键字传入闭包,此时要想像PHP函数或方法的参数一样,使用逗号分割多个参数。
3).PHP闭包仍然是对象,可以使用$this关键字获取闭包的内部状态。闭包的默认状态里面有一个__invoke()
魔术方法和bindTo()
方法。
4).bindTo()
方法为闭包增加了一些有趣的东西。我们可以使用这个方法把Closure对象内部状态绑定到其他对象上。bindTo()
方法的第二个参数可以指定绑定闭包的那个对象所属的PHP类,这样我们就可以访问这个类的受保护和私有的成员变量。看下面的代码示例:
class App{ protected $route = array(); protected $responseStatus = '200 OK'; protected $responseContentType = 'text/html'; protected $responseBody = 'Hello world'; public function addRoute($routePath, $routeCallback) { $this->routes[$routePath] = $routeCallback->bindTo($this, __CLASS__); } public function dispatch($currentPath) { foreach($this->routes as $routePath => $callback) { if ($routePath === $currentPath) { $callback(); } } header('HTTP/1.1' . $this->responseStatus); header('Content-type: ' . $this->responseContentType); header('Content-length: ' . mb_strlen($this->responseBody)); echo $this->responseBody; }}
我们把路由回调绑定到了当前的App实例上,这样就可以在回调函数中处理App实例的状态了。
$app = new App();$app->addRoute('/users/xiaoxiao', function () { $this->responseContentType = 'application/json;charset=utf8'; $this->responseBody = '{"name" : "xiaoxiao"}';});$app->dispatch('/users/xiaoxiao');
- PHP新特性之闭包、匿名函数
- 现代 PHP 新特性系列(五) —— 闭包和匿名函数
- php 闭包, 匿名函数
- PHP新特性 闭包
- PHP学习笔记——新特性匿名函数
- C++11 新特性之Lambda函数(匿名函数)
- php 函数【匿名函数、闭包】
- php闭包函数(匿名函数)
- PHP匿名函数(闭包函数)
- PHP匿名函数(闭包函数)
- jdk8新特性:Lambda表达式(也称为闭包、可传递的匿名函数)与函数式接口@FunctionalInterface
- PHP匿名函数 闭包简单例子
- PHP匿名函数及闭包
- PHP匿名和闭包函数
- PHP匿名函数及闭包
- php闭包和匿名函数
- php中的匿名函数和闭包
- PHP匿名函数、闭包、function use
- rsync命令----解决远程拷贝一个问题通过scp不能复制ln文件
- Java泛型
- Java快速排序
- jdbc基础
- echo & cat
- PHP新特性之闭包、匿名函数
- Spring3.1.0实现原理分析(十七).MVC请求处理方法参数解析器和返回值解析器
- 基本算法之选择排序
- object-c 入门基础篇
- JAVA操作HDFS案例
- C. Dasha and Password-C. Dasha and Password-暴力|dp思想
- android Notification与BroadcastReceiver结合使用
- 运筹学之排队论
- Centos 6.x docker的安装配置