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 相关文章推荐
实用函数5
Nov 08 PHP
PHP 解决utf-8和gb2312编码转换问题
Mar 18 PHP
PHP ? EasyUI DataGrid 资料存的方式介绍
Nov 07 PHP
PHP 自定义错误处理函数trigger_error()
Mar 26 PHP
PHP中HTML标签过滤技巧
Jan 07 PHP
PHP获取php,mysql,apche的版本信息示例代码
Jan 16 PHP
php中的动态调用实例分析
Jan 07 PHP
详解PHP的Yii框架中自带的前端资源包的使用
Mar 31 PHP
PHP数组函数array_multisort()用法实例分析
Apr 02 PHP
PHP使用pear实现mail发送功能 windows环境下配置pear
Apr 15 PHP
PHP微信开发之模板消息回复
Jun 24 PHP
php 魔术常量详解及实例代码
Dec 04 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
PHP print类函数使用总结
2010/06/25 PHP
php实现文件下载实例分享
2014/06/02 PHP
PHP调用Mailgun发送邮件的方法
2017/05/04 PHP
PHP封装的XML简单操作类完整实例
2017/11/13 PHP
Valerio 发布了 Mootools
2006/09/23 Javascript
JavaScript中Boolean对象的属性解析
2015/10/21 Javascript
JQuery的常用选择器、过滤器、方法全面介绍
2016/05/25 Javascript
vue分类筛选filter方法简单实例
2017/03/30 Javascript
layui弹出层效果实现代码
2017/05/19 Javascript
Javascript中将变量转换为字符串的三种方法
2017/09/19 Javascript
vue中如何让子组件修改父组件数据
2018/06/14 Javascript
微信小程序实现签到功能
2018/10/31 Javascript
微信小程序 调用远程接口 给全局数组赋值代码实例
2019/08/13 Javascript
layer.open 获取不到表单信息的解决方法
2019/09/26 Javascript
关于JS模块化的知识点分享
2019/10/16 Javascript
小程序中使用css var变量(使js可以动态设置css样式属性)
2020/03/31 Javascript
js实现复制粘贴的两种方法
2020/12/04 Javascript
深入Python解释器理解Python中的字节码
2015/04/01 Python
在Python的setuptools框架下生成egg的教程
2015/04/13 Python
安装ElasticSearch搜索工具并配置Python驱动的方法
2015/12/22 Python
Python实现正弦信号的时域波形和频谱图示例【基于matplotlib】
2018/05/04 Python
使用python画个小猪佩奇的示例代码
2018/06/06 Python
Selenium控制浏览器常见操作示例
2018/08/13 Python
python基于C/S模式实现聊天室功能
2019/01/09 Python
Python基础学习之类与实例基本用法与注意事项详解
2019/06/17 Python
Python实用库 PrettyTable 学习笔记
2019/08/06 Python
jenkins配置python脚本定时任务过程图解
2019/10/29 Python
python 初始化一个定长的数组实例
2019/12/02 Python
美国汽车交易网站:Edmunds
2016/08/17 全球购物
爱他美官方海外旗舰店:Aptamil奶粉
2017/12/22 全球购物
美国伴娘礼服商店:Evening Collective
2019/10/07 全球购物
27个经典Linux面试题及答案,你知道几个?
2014/03/11 面试题
高中毕业生个人自我鉴定
2013/11/24 职场文书
计算机维护专业推荐信
2014/02/27 职场文书
建筑工程材料员岗位职责
2015/04/11 职场文书
2015年乡镇科普工作总结
2015/05/13 职场文书