浅析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 相关文章推荐
用Socket发送电子邮件(利用需要验证的SMTP服务器)
Oct 09 PHP
详细介绍PHP应用提速面面观
Oct 09 PHP
PHP中Session的概念
Oct 09 PHP
PHP goto语句简介和使用实例
Mar 11 PHP
PHP利用func_get_args和func_num_args函数实现函数重载实例
Nov 12 PHP
ThinkPHP打开验证码页面显示乱码的解决方法
Dec 18 PHP
支持中文、字母、数字的PHP验证码
May 04 PHP
如何使用php实现评委评分器
Jul 31 PHP
php基础教程
Aug 26 PHP
购物车实现的几种方式优缺点对比
May 02 PHP
php中isset与empty函数的困惑与用法分析
Jul 05 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
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 MYSQL中插入当前时间
2008/04/06 PHP
php去掉字符串的最后一个字符附substr()的用法
2011/03/23 PHP
php empty()与isset()区别的详细介绍
2013/06/17 PHP
php连接sftp的作用以及实例代码
2019/09/23 PHP
JQuery的一些小应用收集
2010/03/27 Javascript
jQuery编辑器KindEditor4.1.4代码高亮显示设置教程
2013/03/01 Javascript
JS短路原理的应用示例 精简代码的途径
2013/12/13 Javascript
JS使用replace()方法和正则表达式进行字符串的搜索与替换实例
2014/04/10 Javascript
node.js+Ajax实现获取HTTP服务器返回数据
2014/11/26 Javascript
setinterval()与clearInterval()JS函数的调用方法
2015/01/21 Javascript
javascript实现连续赋值
2015/08/10 Javascript
Bootstrap组件之下拉菜单,多级菜单及按钮布局方法实例
2017/05/25 Javascript
js实现登录注册框手机号和验证码校验(前端部分)
2017/09/28 Javascript
vue下axios拦截器token刷新机制的实例代码
2020/01/17 Javascript
Python变量和数据类型详解
2017/02/15 Python
Python 实现一行输入多个值的方法
2018/04/21 Python
Pandas读取并修改excel的示例代码
2019/02/17 Python
Python实现的远程文件自动打包并下载功能示例
2019/07/12 Python
python 动态迁移solr数据过程解析
2019/09/04 Python
python单向链表的基本实现与使用方法【定义、遍历、添加、删除、查找等】
2019/10/24 Python
python 爬虫之selenium可视化爬虫的实现
2020/12/04 Python
CSS3 box-shadow属性实例详解
2020/06/19 HTML / CSS
DOUGLAS荷兰:购买香水和化妆品
2020/10/24 全球购物
财务主管岗位职责
2014/02/28 职场文书
工业自动化专业自荐信范文
2014/04/10 职场文书
父母对孩子说的话
2014/04/12 职场文书
2014年廉洁自律承诺书
2014/05/26 职场文书
预备党员思想汇报1000字
2014/10/07 职场文书
庆六一开幕词
2015/01/29 职场文书
教师个人师德总结
2015/02/06 职场文书
生产现场禁烟通知
2015/04/23 职场文书
毕业论文致谢怎么写
2015/05/14 职场文书
《你在为谁工作》心得体会(共8篇)
2016/01/20 职场文书
CSS实现漂亮的时钟动画效果的实例代码
2021/03/30 HTML / CSS
Oracle设置DB、监听和EM开机启动的方法
2021/04/25 Oracle
MySQL 主从复制数据不一致的解决方法
2022/03/18 MySQL