匿名函数和闭包

旧街凉风 提交于 2019-12-01 06:10:07

真正的匿名函数

在PHP5.3引入的众多功能中, 除了匿名函数还有一个特性值得讲讲: 新引入的__invoke 魔幻方法。

这个魔幻方法被调用的时机是: 当一个对象当做函数调用的时候, 如果对象定义了__invoke魔幻方法则这个函数会被调用, 这和C++中的操作符重载有些类似, 例如可以像下面这样使用

###魔术方法__invoke

<?php
class Callme {
    public function __invoke($phone_num) {
        echo "Hello: $num";
    }
}
 
$call = new Callme();
$call(13810688888); // "Hello: 13810688888
?>

#匿名函数的实现 前面介绍了将对象作为函数调用的方法, 聪明的你可能想到在PHP实现匿名函数的方法了,PHP中的匿名函数就的确是通过这种方式实现的。 我们先来验证一下:

<?php
$func = function() {
    echo "Hello, anonymous function";
}
 
echo gettype($func);    // object
echo get_class($func);  // Closure
?>

原来匿名函数也只是一个普通的类而已.

#闭包的使用

PHP使用闭包(Closure)来实现匿名函数, 匿名函数最强大的功能也就在匿名函数所提供的一些动态特性以及闭包效果,

匿名函数在定义的时候如果需要使用作用域外的变量需要使用如下的语法来实现:

use语法

<?php
$name = 'TIPI Tea';
$func = function() use($name) {
    echo "Hello, $name";
}
 
$func(); // Hello TIPI Team
?>

#use说明 这个use语句看起来挺别扭的, 尤其是和Javascript比起来, 不过这也应该是PHP-Core综合考虑才使用的语法, 因为和Javascript的作用域不同, PHP在函数内定义的变量默认就是局部变量, 而在Javascript中则相反, 除了显式定义的才是局部变量, PHP在变异的时候则无法确定变量是局部变量还是上层作用域内的变量, 当然也可能有办法在编译时确定, 不过这样对于语言的效率和复杂性就有很大的影响。

这个语法比较直接, 如果需要访问上层作用域内的变量则需要使用use语句来申明, 这样也简单易读, 说到这里, 其实可以使用use来实现类似global语句的效果。

匿名函数在每次执行的时候都能访问到上层作用域内的变量, 这些变量在匿名函数被销毁之前始终保存着自己的状态, 例如如下的例子:

<?php
function getCounter() {
    $i = 0;
    return function() use($i) { // 这里如果使用引用传入变量: use(&$i)
        echo ++$i;
    };
}
 
$counter = getCounter();
$counter(); // 1
$counter(); // 1
?>

参考来源

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!