浅析PHP中的闭包和匿名函数


Posted in PHP onDecember 25, 2017

闭包是指在创建时封装周围状态的函数。即使闭包所在的环境不存在了,闭包中封装的状态依然存在。

匿名函数就是没有名称的函数。匿名函数可以赋值给变量,还能像其他任何PHP对象那样传递。不过匿名函数仍是函数,因此可以调用,还可以传入参数。匿名函数特别适合作为函数或方法的回调。

注意:理论上讲,闭包和匿名函数是不同的概念。不过,PHP将其视作相同的概念。所以,我们提到闭包时,指的也是匿名函数,反之亦然。

PHP闭包和匿名函数使用的句法与普通函数相同,但闭包和匿名函数其实是 伪装成函数的对象(Closure类的实例) 。

创建闭包

$closure = function($name){
  return sprintf("Hello %s", $name);
}
echo $closure("jerry");
// 检测$closure变量是否是一个闭包
var_dump($closure instanceof Closure);

以上代码创建了一个闭包对象,然后将其赋值给 $closure 变量。闭包和普通的PHP函数很像,使用的句法相同,也接收参数,而且能返回值。

说明:我们之所以能够调用 $closure 变量,是因为这个变量的值是一个闭包,而且闭包对象实现了 __invoke() 魔术方法。只要变量名后有 () ,PHP就会查找并调用 __invoke() 方法。

使用闭包

我们通常把PHP闭包当做当做函数和方法的回调使用。很多PHP函数都会用到回调函数,例如 array_map() preg_replace_callback() .如下示例,我们将用 array_map() 处理数组,将数组每一项自增1:

$nubmers = array_map(function($number){
  return $number++;
}, [1,2,3]);
var_dump($numbers);

附加状态

PHP闭包不会像真正的javascrypt闭包那样自动封装应用的状态,我们必须手动调用闭包对象的 bindTo() 方法或者使用 use 关键字,把状态附加到PHP闭包上。

使用 use 关键字

使用 use 关键字来附加闭包状态更加常见,因此我们先来看这种方式。使用 use 关键字把变量附加闭包上时,附加的变量会记住附加时赋给它的值。

function Car ($name){
  return function($statu)use($name){
    return sprintf("Car %s is %s", $name, $statu); 
  }
}
// 将车名封装在闭包中
$car = Car("bmw");
// 调用车的动作
// 输出--> "bmw is running"
echo $car("running");

注意:使用 use 关键字可以把多个参数传入闭包,此时要像PHP函数或方法的参数一样,使用逗号分隔多个参数。

使用 bindTo() 方法附加闭包的状态

与其它PHP对象类似,每个闭包实例都可以使用 $this 关键字获取闭包的内部状态。闭包对象的默认状态没什么用,不过有一个 __invoke() 魔术方法和 bindTo() 方法。

bindTo() 方法为闭包增加了一些有趣的潜力。我们可以使用这个方法把 Closure 对象的内部状态绑定到其它对象上。

bindTo() 方法的第二个参数很重要,其作用是指定绑定闭包的那个对象所属的PHP类。因此,闭包可以访问绑定闭包的对象中受保护和私有的成员变量。

class TestClosure
{
  private $name=[];
  private $age;
  private $sex;
  public function addPerson($name, $personCallback){
    // 将闭包对象绑定当前实例
    $this->name[$name] = $personCallback->bindTo($this, __CLASS__);
  }
  public function display($name){
    foreach ($this->name as $key => $callback){
      if($key == $name){
        // 执行闭包对象,将闭包状态附加到类
        $callback();
      }
    }
    echo "name : {$name}\n";
    echo "age : {$this->age}\n";
    echo "sex : {$this->sex}\n";
  }
}
$person = new TestClosure();
$person->addPerson("jerry", function(){
  $this->age = 19;
  $this->sex = "man";
});
$person->display("jerry");
/** output
name : jerry
age : 19
sex : man
*/

总结

以上所述是小编给大家介绍的PHP中的闭包和匿名函数,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

PHP 相关文章推荐
用PHP生成html分页列表的代码
Mar 18 PHP
深入apache host的配置详解
Jun 09 PHP
ThinkPHP页面跳转success与error方法概述
Jun 25 PHP
php中常量DIRECTORY_SEPARATOR用法深入分析
Nov 14 PHP
ThinkPHP实现递归无级分类――代码少
Jul 29 PHP
PHP的Yii框架使用中的一些错误解决方法与建议
Aug 21 PHP
PHP中的use关键字及文件的加载详解
Nov 28 PHP
thinkphp 验证码 的使用小结
May 07 PHP
详解PHP序列化和反序列化原理
Jan 15 PHP
PHP 获取客户端 IP 地址的方法实例代码
Nov 11 PHP
PHP实现微信提现功能(微信商城)
Nov 21 PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
Dec 20 PHP
thinkphp5 加载静态资源路径与常量的方法
Dec 24 #PHP
PHP读取并输出XML文件数据的简单实现方法
Dec 22 #PHP
ajax+php实现无刷新验证手机号的实例
Dec 22 #PHP
Thinkphp5行为使用方法汇总
Dec 21 #PHP
PHP二维数组实现去除重复项的方法【保留各个键值】
Dec 21 #PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
Dec 21 #PHP
PHP实现生成模糊图片的方法示例
Dec 21 #PHP
You might like
php 文件上传类代码
2011/08/06 PHP
如何让CI框架支持service层
2014/10/29 PHP
php将12小时制转换成24小时制的方法
2015/03/31 PHP
Yii rules常用规则示例
2016/03/15 PHP
PHP利用超级全局变量$_GET来接收表单数据的实例
2016/11/05 PHP
js常用函数 不错
2006/09/08 Javascript
写出更好的JavaScript之undefined篇(上)
2009/11/22 Javascript
jquery实现智能感知连接外网搜索
2013/05/21 Javascript
jquery鼠标放上去显示悬浮层即弹出定位的div层
2014/04/25 Javascript
让checkbox不选中即将选中的checkbox不选中
2014/07/11 Javascript
JavaScript 学习笔记之操作符
2015/01/14 Javascript
jquery 插件实现多行文本框[textarea]自动高度
2015/03/04 Javascript
PHP+MySQL+jQuery随意拖动层并即时保存拖动位置实例讲解
2015/10/09 Javascript
JS及PHP代码编写八大排序算法
2016/07/12 Javascript
Bootstrap基本插件学习笔记之模态对话框(16)
2016/12/08 Javascript
JS定时检测任务任务完成后执行下一步的解决办法
2016/12/22 Javascript
深入理解jquery的$.extend()、$.fn和$.fn.extend()
2017/07/08 jQuery
浅谈angular2路由预加载策略
2017/10/04 Javascript
JavaScript实现短信倒计时60s
2017/10/09 Javascript
使用vue 国际化i18n 实现多实现语言切换功能
2018/10/11 Javascript
详解vue 在移动端体验上的优化解决方案
2019/05/20 Javascript
Vue搭建后台系统需要注意的问题
2019/11/08 Javascript
javascript设计模式 ? 桥接模式原理与应用实例分析
2020/04/13 Javascript
JS表单验证插件之数据与逻辑分离操作实例分析【策略模式】
2020/05/01 Javascript
如何利用nodejs实现命令行游戏
2020/11/24 NodeJs
python使用自定义user-agent抓取网页的方法
2015/04/15 Python
python去掉 unicode 字符串前面的u方法
2018/10/21 Python
Python如何调用外部系统命令
2019/08/07 Python
HTML5之SVG 2D入门8—文档结构及相关元素总结
2013/01/30 HTML / CSS
介绍一下UNIX启动过程
2013/11/14 面试题
团员学习总结的自我评价范文
2013/10/14 职场文书
大学生创业事迹材料
2014/12/30 职场文书
家长会开场白和结束语
2015/05/29 职场文书
公司职员入党自传书
2015/06/26 职场文书
2015年安全生产月工作总结
2015/07/27 职场文书
postgresql之greenplum字符串去重拼接方式
2023/05/08 PostgreSQL