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编码规范-php coding standard
Mar 16 PHP
php短域名转换为实际域名函数
Jan 17 PHP
php下通过curl抓取yahoo boss 搜索结果的实现代码
Jun 10 PHP
基于empty函数的判断详解
Jun 17 PHP
wordpress自定义url参数实现路由功能的代码示例
Nov 28 PHP
php实现简单文件下载的方法
Jan 30 PHP
ThinkPHP中Widget扩展的两种写法及调用方法详解
May 04 PHP
Laravel Intervention/image图片处理扩展包的安装、使用与可能遇到的坑详解
Nov 14 PHP
使用 PHP Masked Package 屏蔽敏感数据的实现方法
Oct 15 PHP
laravel orm 关联条件查询代码
Oct 21 PHP
Yii框架多语言站点配置方法分析【中文/英文切换站点】
Apr 07 PHP
Swoole源码中如何查询Websocket的连接问题详解
Aug 30 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
同台服务器使用缓存APC效率高于Memcached的演示代码
2010/02/16 PHP
PHP的cURL库功能简介 抓取网页、POST数据及其他
2011/04/07 PHP
关于crontab的使用详解
2013/06/24 PHP
PHP实现ftp上传文件示例
2014/08/21 PHP
Linux(CentOS)下PHP扩展PDO编译安装的方法
2016/04/07 PHP
Javascript中valueOf与toString区别浅析
2013/03/19 Javascript
代码获取历史上的今天发生的事
2014/04/11 Javascript
解决node-webkit 不支持html5播放mp4视频的方法
2015/03/11 Javascript
Javascript中setTimeOut和setInterval的定时器用法
2015/06/12 Javascript
JS中改变this指向的方法(call和apply、bind)
2016/03/26 Javascript
利用JavaScript阻止表单提交的两种方法
2016/08/11 Javascript
原生js实现jquery函数animate()动画效果的简单实例
2016/08/21 Javascript
关于vue.js弹窗组件的知识点总结
2016/09/11 Javascript
KnockoutJS 3.X API 第四章之表单submit、enable、disable绑定
2016/10/10 Javascript
Angular2 之 路由与导航详细介绍
2017/05/26 Javascript
vue slot 在子组件中显示父组件传递的模板
2018/03/02 Javascript
浅谈Vue2.0中v-for迭代语法的变化(key、index)
2018/03/06 Javascript
微信小程序购物车、父子组件传值及calc的注意事项总结
2018/11/14 Javascript
解决vue项目,npm run build后,报路径错的问题
2020/08/13 Javascript
在Gnumeric下使用Python脚本操作表格的教程
2015/04/14 Python
Python中转换角度为弧度的radians()方法
2015/05/18 Python
Python小进度条显示代码
2019/03/05 Python
python3获取当前目录的实现方法
2019/07/29 Python
SELENIUM自动化模拟键盘快捷键操作实现解析
2019/10/28 Python
Python用类实现扑克牌发牌的示例代码
2020/06/01 Python
Python select及selectors模块概念用法详解
2020/06/22 Python
Python3中对json格式数据的分析处理
2021/01/28 Python
Kipling澳洲官网:购买凯浦林包包
2020/12/17 全球购物
物业电工岗位职责
2013/11/20 职场文书
校本教研工作制度
2014/01/22 职场文书
学生保证书
2015/01/16 职场文书
中秋节感想
2015/08/10 职场文书
IDEA使用SpringAssistant插件创建SpringCloud项目
2021/06/23 Java/Android
Java8中接口的新特性使用指南
2021/11/01 Java/Android
MySQL 开窗函数
2022/02/15 MySQL
Python中字符串对象语法分享
2022/02/24 Python