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 相关文章推荐
用PHP4访问Oracle815
Oct 09 PHP
PHP新手上路(八)
Oct 09 PHP
php设计模式 Bridge (桥接模式)
Jun 26 PHP
PHP依赖倒置(Dependency Injection)代码实例
Oct 11 PHP
php实现粘贴截图并完成上传功能
May 17 PHP
Linux系统递归生成目录中文件的md5的方法
Jun 29 PHP
php传值方式和ajax的验证功能
Mar 27 PHP
php基于SQLite实现的分页功能示例
Jun 21 PHP
PHP调用全国天气预报数据接口查询天气示例
Feb 20 PHP
php如何把表单内容提交到数据库
Jul 08 PHP
使用laravel和ECharts实现折线图效果的例子
Oct 09 PHP
PHP封装请求类实例分析【基于Yii框架】
Oct 17 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中批量修改文件后缀名的函数代码
2011/10/23 PHP
如何修改和添加Apache的默认站点目录
2013/07/05 PHP
浅析php学习的路线图
2013/07/10 PHP
PHP中filter函数校验数据的方法详解
2015/07/31 PHP
php的debug相关函数用法示例
2016/07/11 PHP
PHP实现上传图片到 zimg 服务器
2016/10/19 PHP
php实现的三个常用加密解密功能函数示例
2017/11/06 PHP
PHP实现的无限分类类库定义与用法示例【基于thinkPHP】
2018/08/06 PHP
javascript各浏览器中option元素的表现差异
2011/04/07 Javascript
js 中的switch表达式使用示例
2020/06/03 Javascript
从零学JSON之JSON数据结构
2014/05/19 Javascript
Javascript中匿名函数的调用与写法实例详解(多种)
2016/01/26 Javascript
修复jQuery tablesorter无法正确排序的bug(加千分位数字后)
2016/03/30 Javascript
jQuery插件pagination实现无刷新分页
2016/05/21 Javascript
jquery计算出left和top,让一个div水平垂直居中的简单实例
2016/07/13 Javascript
Bootstrap框架结合jQuery仿百度换肤功能实例解析
2016/09/17 Javascript
JS设计模式之策略模式概念与用法分析
2018/02/05 Javascript
原生js代码能实现call和bind吗
2019/07/31 Javascript
VsCode与Node.js知识点详解
2019/09/05 Javascript
详解mpvue开发微信小程序基础知识
2019/09/23 Javascript
解决vue更新路由router-view复用组件内容不刷新的问题
2019/11/04 Javascript
[15:15]教你分分钟做大人:狙击手
2014/10/30 DOTA
Python 爬虫学习笔记之多线程爬虫
2016/09/21 Python
使用Python3制作TCP端口扫描器
2017/04/17 Python
Python3实现的字典、列表和json对象互转功能示例
2018/05/22 Python
python 去除txt文本中的空格、数字、特定字母等方法
2018/07/24 Python
对Python3 * 和 ** 运算符详解
2019/02/16 Python
Grid 宫格常用布局的实现
2020/01/10 HTML / CSS
国外平面设计素材网站:The Hungry JPEG
2017/03/28 全球购物
女子职高个人自荐书
2014/02/01 职场文书
材料加工工程求职信
2014/02/19 职场文书
2014年秋季开学寄语
2014/08/02 职场文书
三严三实心得体会范文
2014/10/13 职场文书
大学生如何逃脱“毕业季创业队即散伙”魔咒?
2019/08/19 职场文书
用python画城市轮播地图
2021/05/28 Python
Vue CLI中模式与环境变量的深入详解
2021/05/30 Vue.js