未加星标

PHP新特性之闭包、匿名函数

字体大小 | |
[开发(php) 所属分类 开发(php) | 发布者 店小二03 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏
闭包 闭包是什么?

1).闭包和匿名函数php5.3中被引入。

2).闭包是指在创建时封装函数周围状态的函数,即使闭包所在的环境不存在了,闭包封装的状态依然存在,这一点和javascript的闭包特性很相似。

3).匿名函数就是没有名称的函数,匿名函数可以赋值给变量,还可以像其他任何PHP对象一样传递。可以将匿名函数和闭包视作相同的概念。

4).需要注意的是闭包使用的语法和普通函数相同,但是他其实是伪装成函数的对象,是Closure类的实例。闭包和字符串或整数一样,是一等值类型。

创建闭包 $closure = function ($name) { 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专题系列目录地址: github.com/xx19941215/…

PHP专题系列预计写二十篇左右,主要总结我们日常PHP开发中容易忽略的基础知识和现代PHP开发中关于规范、部署、优化的一些实战性建议,同时还有对Javascript语言特点的深入研究。

本文开发(php)相关术语:php代码审计工具 php开发工程师 移动开发者大会 移动互联网开发 web开发工程师 软件开发流程 软件开发工程师

主题: PHPJava变量其实
分页:12
转载请注明
本文标题:PHP新特性之闭包、匿名函数
本站链接:http://www.codesec.net/view/561293.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 开发(php) | 评论(0) | 阅读(48)