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集成FCK的函数代码
Sep 27 PHP
php foreach 参数强制类型转换的问题
Dec 10 PHP
web目录下不应该存在多余的程序(安全考虑)
May 09 PHP
php中将指针移动到数据集初始位置的实现代码[mysql_data_seek]
Nov 01 PHP
PHP操作MySQL事务实例
Nov 05 PHP
php中Socket创建与监听实现方法
Jan 05 PHP
PHP魔术方法的使用示例
Jun 23 PHP
php简单复制文件的方法
May 09 PHP
PHP环境搭建的详细步骤
Jun 30 PHP
php实现在新浪云中使用imagick生成缩略图并上传的方法
Sep 26 PHP
php常用正则函数实例小结
Dec 29 PHP
laravel与thinkphp之间的区别与优缺点
Mar 02 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通过获取头信息判断图片类型的方法
2015/06/26 PHP
laravel 判断查询数据库返回值的例子
2019/10/11 PHP
Gambit vs CL BO3 第二场 2.13
2021/03/10 DOTA
摘自启点的main.js
2008/04/20 Javascript
jQuery 使用手册(三)
2009/09/23 Javascript
JavaScript具有类似Lambda表达式编程能力的代码(改进版)
2010/09/14 Javascript
JavaScript基础篇之变量作用域、传值、传址的简单介绍与实例
2013/06/29 Javascript
JS实现点击图片在当前页面放大并可关闭的漂亮效果
2013/10/18 Javascript
jQuery实现鼠标经过图片预览大图效果
2014/04/10 Javascript
Node.js中创建和管理外部进程详解
2014/08/16 Javascript
浅谈js中的延迟执行和定时执行
2016/05/31 Javascript
JavaScript实现相册弹窗功能(zepto.js)
2016/06/21 Javascript
AngularJS 路由详解和简单实例
2016/07/28 Javascript
Js遍历键值对形式对象或Map形式的方法
2016/08/08 Javascript
AngularJS过滤器filter用法分析
2016/12/11 Javascript
详解vue-Resource(与后端数据交互)
2017/01/16 Javascript
关于HTML5的data-*自定义属性的总结
2018/05/05 Javascript
使用async await 封装 axios的方法
2018/07/09 Javascript
vue实现多条件和模糊搜索功能
2019/05/28 Javascript
回顾Javascript React基础
2019/06/15 Javascript
NodeJS 文件夹拷贝以及删除功能
2019/09/03 NodeJs
[54:58]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第一场 11.25
2020/11/25 DOTA
Python实现的一个简单LRU cache
2014/09/26 Python
利用Python演示数型数据结构的教程
2015/04/03 Python
django静态文件加载的方法
2018/05/20 Python
Python 16进制与中文相互转换的实现方法
2018/07/09 Python
python 实现对数据集的归一化的方法(0-1之间)
2018/07/17 Python
对Python3中bytes和HexStr之间的转换详解
2018/12/04 Python
Python关于__name__属性的含义和作用详解
2020/02/19 Python
Sandro Paris美国官网:典雅别致的法国时尚服饰品牌
2017/12/26 全球购物
Urban Outfitters德国官网:美国跨国生活方式零售公司
2018/05/21 全球购物
新西兰第一的行李箱网站:luggage.co.nz
2019/07/22 全球购物
北京振戎融通Java面试题
2015/09/03 面试题
2015年电话销售工作总结范文
2015/04/20 职场文书
2016中秋节问候语
2015/11/11 职场文书
2019年最新借条范本!
2019/07/08 职场文书