写点什么

【web 开发基础】PHP 的匿名函数和闭包 (40)

作者:迷彩
  • 2022-11-28
    广东
  • 本文字数:1621 字

    阅读完需:约 5 分钟

前言

PHP 匿名函数和闭包使用的句法与普通函数相同,但匿名函和闭包其实可以简单地理解为是伪装成函数的对象。

什么是匿名函数


匿名函数:就是没有名称的函数,匿名函数可以赋值给变量、对象传递。不过匿名函数仍是函数,也就是本质是还是函数,因此可以进行调用,还可以传入参数。匿名函数特别适合作为函数或方法的回调。回调我们前面介绍过,可以通过《【web 开发基础】PHP 自定义回调函数之 call_user_func_array() (36)》这篇文章了解。

什么是闭包

简单讲,闭包就是指有权访问另一个函数作用域中的变量的函数。MDN 上面的说法:闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。简单理解闭包的关键在于:外部函数调用之后其变量对象本应该被销毁,但闭包的存在使得我们仍然可以访问外部函数的变量对象,这就是闭包的重要概念。

闭包:是指在创建时封装周围状态的函数。即使闭包所在的环境不存在了,闭包中封装的状态依然存在。

注:理论上讲,闭包和匿名函数是不同的概念. 只是在 PHP 中将两者视作相同的概念。


PHP 中的匿名函数和闭包

匿名函数

匿名函数与普通函数的区别:

(1)随用随建,省去定义的过程,代码变得更加简洁

(2)省去了普通函数命名的过程


PHP 支持回调函数(callback),和其他高级语言相比是增分比较多的一项功能,但和 JavaScript 相比,PHP5.3 以前的回调函数使用并不是很灵活,只有“字符串的函数名”和“使用 create_function 的返回值”两种选择。而在 PHP5.3 以后,我们又多了一个选择——匿名函数(Anonymous functions),也叫闭包(closures),它允许临时创建一个没有指定名称的函数,常用作回调函数参数的值。当然,也有其他应用的情况。匿名函数的语法如下:

$func = function(){    };//带结束符,相当于一句完整的表达式
复制代码

下面我们通过一段代码简单了解匿名函数的使用:

<?php$func = function($param){     echo($param);};$func("你好");
复制代码

执行结果:

匿名函数也可以作为一个变量的值来使用,可以直接将匿名函数作为参数传给回调函数,是匿名函数最常见的用法,匿名函数时一句表达式,一定不要忘了加上分号“;”。还可以在函数中定义一个匿名函数:

<?php//函数里定义一个匿名函数,并且调用它function demo(){    $func = function($param){        echo $param;    };    $func('你好');}demo();
复制代码

执行结果:


调用回调函数时将匿名函数作为参数的代码如下:

<?php//将匿名函数作为参数传递function func($callback){    $callback();}
$val = "你好";func(function() use (&$val){ echo "闭包函数传入的参数为:". $val;});
复制代码

执行结果:

通过函数还可以把匿名函数返回:

<?php// 在函数中把匿名函数返回,返回后调用它function demo(){    return $func = function($param){        echo $param;    };}$data = demo();$data('hello world');
复制代码

执行结果如下:


闭包

闭包的一个重要的概念就是在内部函数中可以使用外部变量,需要通过关键字 use 来连接闭包和外界变量,这些变量都必须在函数或类的头部声明。闭包函数是从父作用域中继承变量,与使用全局变量是不同的。全局变量存在于一个全局的范围中,无论当前正在执行的是哪个函数,而闭包的父作用域是定义该闭包的函数,不一定是调用它的函数。

闭包的语法如下:

$func = function() use(){ 。。。};
复制代码

下面我们通过具体的代码了解关键字 use 的使用:

<?php//将匿名函数作为参数传递function func($callback){    $callback();}
$val = "你好";func(function() use (&$val){ echo "闭包函数传入的参数为:". $val;});
复制代码

执行结果如下:

use 引用的变量是 $val 的副本,如果要完全引用,就要像上面的例子一样要在变量的前面加上符号“&”,上面所介绍的 closure 只是全局的的匿名函数,如果现在我们想指定一个类有一个匿名函数,那这个匿名函数的访问范围不再是全局的,而是一个类的访问范围。关于 PHP Closure 类的声明和使用,我们后续单独详细介绍。

发布于: 刚刚阅读数: 4
用户头像

迷彩

关注

我的工作是常年写bug|公众号:编程架构之美 2020-06-18 加入

修bug的菜鸟~公众号:“互联网有啥事”已改名为“编程架构之美”

评论

发布
暂无评论
【web 开发基础】PHP的匿名函数和闭包 (40)_闭包 closure_迷彩_InfoQ写作社区