浅析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下关于Cannot use a scalar value as an array的解决办法
Aug 08 PHP
php 实现进制转换(二进制、八进制、十六进制)互相转换实现代码
Oct 22 PHP
提示Trying to clone an uncloneable object of class Imagic的解决
Oct 27 PHP
Php图像处理类代码分享
Jan 19 PHP
Php无限级栏目分类读取的实现代码
Feb 19 PHP
PHP文件读写操作相关函数总结
Nov 18 PHP
PHP查询附近的人及其距离的实现方法
May 11 PHP
Yii2框架使用计划任务的方法
May 25 PHP
php for 循环使用的简单实例
Jun 02 PHP
php实现的生成迷宫与迷宫寻址算法完整实例
Nov 06 PHP
PHP中数组转换为SimpleXML教程
Jan 27 PHP
PHP函数积累总结
Mar 19 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面向对象全攻略 (十七) 自动加载类
2009/09/30 PHP
php生成网页桌面快捷方式
2017/05/05 PHP
Yii2框架自定义类统一处理url操作示例
2019/05/25 PHP
php并发加锁问题分析与设计代码实例讲解
2021/02/26 PHP
JS在IE和FireFox之间常用函数的区别小结
2010/03/12 Javascript
JavaScript与Image加载事件(onload)、加载状态(complete)
2011/02/14 Javascript
P3P Header解决Cookie跨域的问题
2013/03/12 Javascript
js模仿hover的具体实现代码
2013/12/30 Javascript
javascript中的Base64、UTF8编码与解码详解
2015/03/18 Javascript
javaScript中with函数用法实例分析
2015/06/08 Javascript
javascript最基本的函数汇总
2015/06/25 Javascript
jQuery实现仿微软首页感应鼠标变化滑动窗口效果
2015/10/08 Javascript
BootStrap创建响应式导航条实例代码
2016/05/31 Javascript
js滚轮事件兼容性问题需要注意哪些
2016/11/15 Javascript
js实现前端图片上传即时预览功能
2017/08/02 Javascript
angularjs实现过滤并替换关键字小功能
2017/09/19 Javascript
vue2.0使用swiper组件实现轮播效果
2017/11/27 Javascript
[28:48]《真视界》- 2017年国际邀请赛
2017/09/27 DOTA
python实现RSA加密(解密)算法
2016/02/17 Python
python的paramiko模块实现远程控制和传输示例
2017/10/13 Python
基于numpy.random.randn()与rand()的区别详解
2018/04/17 Python
Python爬虫包BeautifulSoup学习实例(五)
2018/06/17 Python
python基础梳理(一)(推荐)
2019/04/06 Python
python中添加模块导入路径的方法
2021/02/03 Python
探究 canvas 绘图中撤销(undo)功能的实现方式详解
2018/05/17 HTML / CSS
使用HTML5在网页中嵌入音频和视频播放的基本方法
2016/02/22 HTML / CSS
Betsey Johnson官网:妖娆可爱的连衣裙及鞋子、手袋和配件
2016/12/30 全球购物
英国著名药妆店:Superdrug
2021/02/13 全球购物
汽车检测与维修应届毕业生求职信
2013/10/19 职场文书
班级学雷锋活动总结
2014/06/26 职场文书
企业领导班子四风对照检查材料
2014/09/27 职场文书
房屋授权无偿使用证明
2014/11/29 职场文书
艺术节开幕词
2015/01/28 职场文书
介绍长城的导游词
2015/01/30 职场文书
Python学习之异常中的finally使用详解
2022/03/16 Python
Nginx禁止ip访问或非法域名访问
2022/04/07 Servers