PHP 闭包详解及实例代码


Posted in PHP onSeptember 28, 2016

闭包和匿名函数在PHP5.3.0中引入的。

闭包是指:创建时封装周围状态的函数。即使闭包所处的环境不存在了,闭包中封装的状态依然存在。

理论上,闭包和匿名函数是不同的概念。但是PHP将其视作相同概念。

实际上,闭包和匿名函数是伪装成函数的对象。他们是Closure类的实例。

闭包和字符串、整数一样,是一等值类型。

创建闭包

<?php
$clousre = function ($name) {
return 'Hello ' . $name;
};
echo $closure('nesfo');

我们之所以能调用$closure变量,是因为这个变量的值是一个闭包,而且闭包对象实现了__invoke()魔术方法。只要变量名后有(),PHP就会查找并调用__invoke()方法。通常会把PHP闭包当作函数的回调使用。array_map(), preg_replace_callback()方法都会用到回调函数,这是使用闭包的最佳时机!

举个例子:

<?php
$numbersPlusOne = array_map(function ($number) {
return $number + 1;
}, [1, 2, 3]);
print_r($numbersPlusOne);

得到结果:

[2, 3, 4]

在闭包出现之前,只能单独创建具名函数,然后使用名称引用那个函数。这么做,代码执行会稍微慢点,而且把回调的实现和使用场景隔离了。

<?php
function incrementNum ($number) {
return $number + 1;
}
$numbersPlusOne = array_map('incrementNum', [1, 2, 3]);
print_r($numbersPlusOne);

附加状态

匿名函数不止可以当回调使用,还可以为PHP附加并封装状态。

PHP中,必须手动调用闭包对象的bindTo()方法或者使用use关键字,才能把状态附加到PHP闭包上。

<?php
function enclosePerson ($name) {
return function ($doCommand) use ($name) {
return $name . ', ' . $doCommand;
}
}
$clay = enclosePerson('Clay');
echo $clay('get me sweet tea!');

得到结果:

"Clay, get me sweet tea!"

PHP闭包是对象,每个闭包实例都可以使用$this关键字获取闭包的内部状态。闭包对象的默认状态没什么用,只有__invoke()方法和bindTo方法而已。

我们可以使用bindTo()这个方法,将Closure对象的内部状态绑定到其它对象上。

bindTo()方法的第二个参数:其作用是指定绑定闭包的那个对象所属的PHP类。因此,闭包可以访问绑定闭包的对象中受保护和私有的成员。

PHP框架经常使用bindTo()方法把路由URL映射到匿名回调函数上。这么做可以在这个匿名函数中使用$this关键字引用重要的应用对象。

使用bindTo()方法附加闭包状态

<?php
class App
{
protected $routes = [];
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;
}
}
<?php
$app = new App();
$app->addRoute('/user/nesfo', function () {
$this->responseContentType = 'application/json; charset=utf8';
$this->responseBody = '{"name": "nesfo"}';
});
$app->dispatch('/user/nesfo');

以上就是对PHP 闭包资料的资料整理,后续继续补充相关资料谢谢大家对本站的支持!

PHP 相关文章推荐
PHP学习笔记 (1) 环境配置与代码调试
Jun 19 PHP
php中使用parse_url()对网址进行解析的实现代码(parse_url详解)
Jan 03 PHP
解析左右值无限分类的实现算法
Jun 20 PHP
浅析php插件 HTMLPurifier HTML解析器
Jul 01 PHP
php实现屏蔽掉黑帽SEO的搜索关键字
Apr 15 PHP
PHP实现清除wordpress里恶意代码
Oct 21 PHP
WordPress中限制非管理员用户在文章后只能评论一次
Dec 31 PHP
php进行ip地址掩码运算处理的方法
Jul 11 PHP
php出租房数据管理及搜索页面
May 23 PHP
PHP封装的非对称加密RSA算法示例
May 28 PHP
PHP单元测试配置与使用方法详解
Dec 27 PHP
TP5框架使用QueryList采集框架爬小说操作示例
Mar 26 PHP
php类的自动加载操作实例详解
Sep 28 #PHP
PHP对象克隆clone用法示例
Sep 28 #PHP
PHP简单遍历对象示例
Sep 28 #PHP
PHP标准类(stdclass)用法示例
Sep 28 #PHP
PHP类型约束用法示例
Sep 28 #PHP
PHP类和对象相关系统函数与运算符小结
Sep 28 #PHP
PHP序列化操作方法分析
Sep 28 #PHP
You might like
Excel数据导入Mysql数据库的实现代码
2008/06/05 PHP
jQuery ajax在GBK编码下表单提交终极解决方案(非二次编码方法)
2010/10/20 Javascript
js各种验证文本框输入格式(正则表达式)
2010/10/22 Javascript
限制上传文件大小和格式的jQuery插件实例
2015/01/24 Javascript
详解JavaScript基于面向对象之创建对象(2)
2015/12/10 Javascript
javascript使用Promise对象实现异步编程
2016/03/01 Javascript
Javascript实现图片不间断滚动的代码
2016/06/22 Javascript
js实现手机拍照上传功能
2017/01/17 Javascript
vue构建单页面应用实战
2017/04/10 Javascript
简单谈谈JS中的正则表达式
2017/09/11 Javascript
vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法
2018/07/12 Javascript
浅谈Vue.js中如何实现自定义下拉菜单指令
2019/01/06 Javascript
NodeJS多种创建WebSocket监听的方式(三种)
2020/06/04 NodeJs
virtualenv实现多个版本Python共存
2017/08/21 Python
浅谈使用Python变量时要避免的3个错误
2017/10/30 Python
Python统计python文件中代码,注释及空白对应的行数示例【测试可用】
2018/07/25 Python
对python内置map和six.moves.map的区别详解
2018/12/19 Python
python itchat给指定联系人发消息的方法
2019/06/11 Python
Pytorch实现GoogLeNet的方法
2019/08/18 Python
wxPython多个窗口的基本结构
2019/11/19 Python
使用 Python 处理3万多条数据只要几秒钟
2020/01/19 Python
Python unittest单元测试框架及断言方法
2020/04/15 Python
Python 转移文件至云对象存储的方法
2021/02/07 Python
Tory Burch美国官方网站:美国时尚生活品牌
2016/08/01 全球购物
在线购买世界上最好的酒:BoozeBud
2018/06/07 全球购物
New Balance加拿大官方网站:运动鞋和健身服装
2018/11/19 全球购物
乌克兰排名第一的在线旅游超市:Farvater.Travel
2020/01/02 全球购物
2014年大学生就业规划书
2014/04/04 职场文书
2014年护士工作总结范文
2014/11/11 职场文书
审查起诉阶段律师意见书
2015/05/19 职场文书
如何用PHP实现多线程编程
2021/05/26 PHP
HTML+CSS制作心跳特效的实现
2021/05/26 HTML / CSS
在前女友婚礼上,用Python破解了现场的WIFI还把名称改成了
2021/05/28 Python
MySQL深度分页(千万级数据量如何快速分页)
2021/07/25 MySQL
Spring Bean是如何初始化的详解
2022/03/22 Java/Android
JS函数式编程实现XDM一
2022/06/16 Javascript