浅析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 相关文章推荐
Zend studio for eclipse中使php可以调用mysql相关函数的设置方法
Oct 13 PHP
php5 apache 2.2 webservice 创建与配置(java)
Jan 27 PHP
phpmyadmin显示utf8_general_ci中文乱码的问题终级篇
Apr 08 PHP
浅析关于PHP位运算的简单权限设计
Jun 30 PHP
php下载excel无法打开的解决方法
Dec 24 PHP
PHP修改session_id示例代码
Jan 08 PHP
PHP中读取照片exif信息的方法
Aug 20 PHP
php curl抓取网页的介绍和推广及使用CURL抓取淘宝页面集成方法
Nov 30 PHP
PhpStorm本地断点调试的方法步骤
May 21 PHP
workerman结合laravel开发在线聊天应用的示例代码
Oct 30 PHP
详解php伪造Referer请求反盗链资源
Jan 24 PHP
thinkphp5框架前后端分离项目实现分页功能的方法分析
Oct 08 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实现无限极分类图文教程
2014/11/25 PHP
php计算两个坐标(经度,纬度)之间距离的方法
2015/04/17 PHP
微信获取用户地理位置信息的原理与步骤
2015/11/12 PHP
使用Composer安装Yii框架的方法
2016/03/15 PHP
阿里云Win2016安装Apache和PHP环境图文教程
2018/03/11 PHP
PHP标准库 (SPL)――Countable用法示例
2020/06/05 PHP
javascript之通用简单的table选项卡实现(二)
2010/05/09 Javascript
基于jquery的has()方法以及与find()方法以及filter()方法的区别详解
2013/04/26 Javascript
如何在指定的地方插入html内容和文本内容
2013/12/23 Javascript
点击button获取text内容并改变样式的js实现
2014/09/09 Javascript
node.js中的path.resolve方法使用说明
2014/12/08 Javascript
JavaScript中Number.NEGATIVE_INFINITY值的使用详解
2015/06/05 Javascript
详解JavaScript ES6中的Generator
2015/07/28 Javascript
FullCalendar日历插件应用之数据展现(一)
2015/12/23 Javascript
javascript每日必学之条件分支
2016/02/17 Javascript
JS打印组合功能
2016/08/04 Javascript
AngularJS  $on、$emit和$broadcast的使用
2016/09/05 Javascript
微信小程序 http请求详细介绍
2016/10/09 Javascript
Angular.js自定义指令学习笔记实例
2017/02/24 Javascript
详解Node.js一行命令上传本地文件到服务器
2019/04/22 Javascript
微信小程序 确认框的实现(附代码)
2019/07/23 Javascript
vue中template的三种写法示例
2020/10/21 Javascript
vue组件中传值EventBus的使用及注意事项说明
2020/11/16 Javascript
[01:51]2014DOTA2国际邀请赛 这个赛场没有失败者VGTi5再见
2014/07/23 DOTA
判断网页编码的方法python版
2016/08/12 Python
python微信公众号开发简单流程
2018/03/23 Python
python 实现 hive中类似 lateral view explode的功能示例
2020/05/18 Python
解决pytorch 交叉熵损失输出为负数的问题
2020/07/07 Python
kmart凯马特官网:美国最大的打折零售商和全球最大的批发商之一
2016/11/17 全球购物
关于成绩下滑的自我检讨书
2014/09/20 职场文书
反腐倡廉剖析材料
2014/09/30 职场文书
个人债务授权委托书范本
2014/10/05 职场文书
2015年党风廉政承诺书
2015/01/22 职场文书
学生会工作感言
2015/08/07 职场文书
《老人与海鸥》教学反思
2016/02/16 职场文书
企业版Windows 11有哪些新功能? Win11适用于企业的功能介绍
2021/11/21 数码科技