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&amp;&amp;mysql)四
Oct 09 PHP
PHP学习之字符串比较和查找
Apr 17 PHP
Zend的MVC机制使用分析(二)
May 02 PHP
对PHP语言认识上需要避免的10大误区
Jun 12 PHP
PHP实现Javascript中的escape及unescape函数代码分享
Feb 10 PHP
PHP安全上传图片的方法
Mar 21 PHP
ajax+php控制所有后台函数调用
Jul 15 PHP
开启PHP Static 关键字之旅模式
Nov 13 PHP
php单链表实现代码分享
Jul 04 PHP
浅谈php处理后端&amp;接口访问超时的解决方法
Oct 29 PHP
php+ajax简单实现全选删除的方法
Dec 06 PHP
Yii框架小部件(Widgets)用法实例详解
May 15 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
SONY SRF-40W电路分析
2021/03/02 无线电
php 将bmp图片转为jpg等其他任意格式的图片
2009/06/29 PHP
thinkphp模板输出技巧汇总
2014/11/24 PHP
php使用pthreads v3多线程实现抓取新浪新闻信息操作示例
2020/02/21 PHP
Javascript 鼠标移动上去 滑块跟随效果代码分享
2013/11/23 Javascript
详解JavaScript ES6中的Generator
2015/07/28 Javascript
JS实现三级折叠菜单特效,其它级可自动收缩
2015/08/06 Javascript
js简单实现表单中点击按钮动态增加输入框数量的方法
2015/08/18 Javascript
jQuery中设置form表单中action值的实现方法
2016/05/25 Javascript
全面了解JavaScirpt 的垃圾(garbage collection)回收机制
2016/07/11 Javascript
javascript实现获取图片大小及图片等比缩放的方法
2016/11/24 Javascript
Javascript this 函数深入详解
2016/12/13 Javascript
Node.js中流(stream)的使用方法示例
2017/07/16 Javascript
JavaScript Date对象应用实例分享
2017/10/30 Javascript
基于JavaScript 性能优化技巧心得(分享)
2017/12/11 Javascript
微信小程序实现折叠展开效果
2018/07/19 Javascript
vue 解决路由只变化参数页面组件不更新问题
2019/11/05 Javascript
在Vue中使用Echarts实例图的方法实例
2020/10/10 Javascript
Python绑定方法与非绑定方法详解
2017/08/18 Python
Ubuntu安装Jupyter Notebook教程
2017/10/18 Python
python+pandas生成指定日期和重采样的方法
2018/04/11 Python
使用django-guardian实现django-admin的行级权限控制的方法
2018/10/30 Python
使用Python制作简单的小程序IP查看器功能
2019/04/16 Python
使用python实现微信小程序自动签到功能
2020/04/27 Python
html+css实现自定义图片上传按钮功能
2019/09/04 HTML / CSS
世界上最大的糖果店:Dylan’s Candy Bar
2017/11/07 全球购物
英国排名第一的礼品体验公司:Red Letter Days
2018/08/16 全球购物
办公室主任个人对照检查材料思想汇报
2014/10/11 职场文书
英语教师求职信范文
2015/03/20 职场文书
2015年劳动部工作总结
2015/05/23 职场文书
员工离职证明范本
2015/06/12 职场文书
扩展多台相同的Web服务器
2021/04/01 Servers
CSS的class与id常用的命名规则
2021/05/18 HTML / CSS
深入详解JS函数的柯里化
2021/06/09 Javascript
基于Go语言构建RESTful API服务
2021/07/25 Golang
Python中第三方库Faker的使用详解
2022/04/02 Python