浅析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 相关文章推荐
不用iconv库的gb2312与utf-8的互换函数
Oct 09 PHP
php str_pad() 将字符串填充成指定长度的字符串
Feb 23 PHP
PHP文件打开、关闭、写入的判断与执行代码
May 24 PHP
PHP详解ASCII码对照表与字符转换
Dec 05 PHP
php删除页面记录 同时刷新页面 删除条件用GET方式获得
Jan 10 PHP
php 判断数组是几维数组
Mar 20 PHP
php自动加载机制的深入分析
Jun 08 PHP
实例讲解yii2.0在php命令行中运行的步骤
Dec 01 PHP
php解决和避免form表单重复提交的几种方法
Aug 31 PHP
PHP工厂模式的日常使用
Mar 20 PHP
laravel使用Faker数据填充的实现方法
Apr 12 PHP
利用PHP计算有多少小于当前数字的数字方法示例
Aug 26 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变量引用的面试题
2010/08/08 PHP
PHP 如何利用phpexcel导入数据库
2013/08/24 PHP
PHP中$_SERVER的详细参数与说明介绍
2013/10/26 PHP
PHP获取当前日期和时间及格式化方法参数
2015/05/11 PHP
php使用PDO获取结果集的方法
2017/02/16 PHP
php中时间函数date及常用的时间计算
2017/05/12 PHP
菜鸟学习JavaScript小实验之函数引用
2010/11/17 Javascript
ExtJs的Date格式字符代码
2010/12/30 Javascript
js获取时间并实现字符串和时间戳之间的转换
2015/01/05 Javascript
原生JavaScript实现滚动条效果
2020/03/24 Javascript
深入理解ES7的async/await的用法
2017/09/09 Javascript
详解vue-cli中模拟数据的两种方法
2018/07/03 Javascript
JS实现中英文混合文字溢出友好截取功能
2018/08/06 Javascript
vue实现局部刷新的实现示例
2019/04/16 Javascript
微信小程序发布新版本时自动提示用户更新的方法
2019/06/07 Javascript
JavaScript创建表格的方法
2020/04/13 Javascript
Webpack3+React16代码分割的实现
2021/03/03 Javascript
python批量下载图片的三种方法
2013/04/22 Python
讲解Python中if语句的嵌套用法
2015/05/14 Python
Tensorflow 训练自己的数据集将数据直接导入到内存
2018/06/19 Python
Python使用while循环花式打印乘法表
2019/01/28 Python
css3背景_动力节点Java学院整理
2017/07/11 HTML / CSS
Giuseppe Zanotti美国官方网站:将鞋履视为高级时装般精心制作
2018/02/06 全球购物
英国办公用品商店:Office Outlet
2018/04/04 全球购物
什么是servlet
2012/05/08 面试题
口腔医学技术应届生求职信
2013/11/09 职场文书
申报职称专业技术个人的自我评价
2013/12/12 职场文书
租房合同协议书
2014/04/09 职场文书
语文教研活动总结
2014/07/02 职场文书
同学聚会通知书
2015/04/20 职场文书
祝福语集锦:送给闺蜜的生日祝福语
2019/10/08 职场文书
上帝为你开了一扇窗之Tkinter常用函数详解
2021/06/02 Python
mysql外连接与内连接查询的不同之处
2021/06/03 MySQL
golang实现一个简单的websocket聊天室功能
2021/10/05 Golang
一篇文章了解正则表达式的替换技巧
2022/02/24 Javascript
Python线程池与GIL全局锁实现抽奖小案例
2022/04/13 Python