浅析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 相关文章推荐
使用MaxMind 根据IP地址对访问者定位
Oct 09 PHP
php中的时间处理
Oct 09 PHP
PHP下几种删除目录的方法总结
Aug 19 PHP
php trim 去除空字符的定义与语法介绍
May 31 PHP
php类的定义与继承用法实例
Jul 07 PHP
CodeIgniter连贯操作的底层原理分析
May 17 PHP
PHP 接入微信扫码支付总结(总结篇)
Nov 03 PHP
php 调用ffmpeg获取视频信息的简单实现
Apr 03 PHP
laravel中的一些简单实用功能
Nov 03 PHP
php中目录操作opendir()、readdir()及scandir()用法示例
Jun 08 PHP
php swoole多进程/多线程用法示例【基于php7nts版】
Aug 12 PHP
php判断IP地址是否在多个IP段内
Aug 18 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 和 MySQL 基础教程(二)
2006/10/09 PHP
ThinkPHP实现跨模块调用操作方法概述
2014/06/20 PHP
php实现图片以base64显示的方法
2016/10/13 PHP
php微信公众号开发之关键词回复
2018/10/20 PHP
flexigrid 参数说明
2010/11/23 Javascript
基于jquery的时间段实现代码
2012/08/02 Javascript
Jquery显示、隐藏元素以及添加删除样式
2013/08/09 Javascript
js禁止页面复制功能禁用页面右键菜单示例代码
2013/08/29 Javascript
JavaScript中的this关键字使用方法总结
2015/03/13 Javascript
jQuery scrollFix滚动定位插件
2015/04/01 Javascript
js简单设置与使用cookie的方法
2016/01/22 Javascript
js计算系统当前日期是星期几的方法
2016/07/14 Javascript
jQuery实现右键菜单、遮罩等效果代码
2016/09/27 Javascript
PHP抓取HTTPS内容和错误处理的方法
2016/09/30 Javascript
js鼠标移动时禁止选中文字
2017/02/19 Javascript
Vue 单文件中的数据传递示例
2017/03/21 Javascript
详解Js中的模块化是如何实现的
2017/10/18 Javascript
前端axios下载excel文件(二进制)的处理方法
2018/07/31 Javascript
全面解析vue router 基本使用(动态路由,嵌套路由)
2018/09/02 Javascript
使用Vue实现简单计算器
2020/02/25 Javascript
Nuxt.js 静态资源和打包的操作
2020/11/06 Javascript
Django静态资源URL STATIC_ROOT的配置方法
2014/11/08 Python
Python实现计算文件夹下.h和.cpp文件的总行数
2015/04/23 Python
python 通过字符串调用对象属性或方法的实例讲解
2018/04/21 Python
python输出电脑上所有的串口名的方法
2019/07/02 Python
简单了解python中的与或非运算
2019/09/18 Python
Python 限定函数参数的类型及默认值方式
2019/12/24 Python
python GUI库图形界面开发之PyQt5工具栏控件QToolBar的详细使用方法与实例
2020/02/28 Python
使用html5实现表格实现标题合并的实例代码
2019/05/13 HTML / CSS
开发中都用到了那些设计模式?用在什么场合?
2014/08/21 面试题
餐厅经理岗位职责和岗位目标
2014/02/13 职场文书
关于运动会的广播稿(10篇)
2014/09/12 职场文书
党员四风问题对照检查材料
2014/09/27 职场文书
出差报告范文
2014/11/06 职场文书
python基于tkinter制作无损音乐下载工具
2021/03/29 Python
Python 中random 库的详细使用
2021/06/03 Python