美文网首页
PHP手册之匿名函数

PHP手册之匿名函数

作者: killtl | 来源:发表于2018-03-20 16:38 被阅读0次

前言

PHP手册系列文章,会挑选一些手册中有意思的评论进行翻译
手册目录: 语言参考---函数---匿名函数
参考详情

评论

  1. 当在你的匿名函数中导入变量时,只是进行简单的复制操作,而且在匿名函数定义的时候就进行了该操作,所以之后对该变量的任何修改都不会影响匿名函数,如果你需要根据变量的变化实时变化,你需要使用引用&
$result = 0;

$one = function()
{ var_dump($result); };

$two = function() use ($result)
{ var_dump($result); };

$three = function() use (&$result)
{ var_dump($result); };

$result++;
$one();    // outputs NULL: $result is not in scope
$two();    // outputs int(0): $result was copied
$three();    // outputs int(1)
  1. 一段代码
/*
(string) $name 是你想添加到类中的方法的名字.
用法 : $Foo->add(function(){},$name);
这样将会向实例中添加public方法;
*/
class Foo
{
    public function add($func,$name)
    {
        $this->{$name} = $func;
    }
    public function __call($func,$arguments){
        call_user_func_array($this->{$func}, $arguments);
    }
}
$Foo = new Foo();
$Foo->add(function(){
    echo "Hello World";
},"helloWorldFunction");
$Foo->add(function($parameterone){
    echo $parameterone;
},"exampleFunction");
$Foo->helloWorldFunction(); /*Output : Hello World*/
$Foo->exampleFunction("Hello PHP"); /*Output : Hello PHP*/
  1. 当你使用匿名函数进行自我递归时, 在use()里面需要用引用操作符&
$recursive = function () use (&$recursive){
    // The function is now available as $recursive
    static $a = 0;
    @print "$a\n";
    if($a++ == 100){
        echo 'over';
        return;
    }
    $recursive();
};
$recursive();

注意,这里会产生一个fatal error:maximum function nesting level of '100' reached,这不是程序的问题,是php.ini里面有一个选项xdebug.max_nesting_level默认设置为100,所以最高能嵌套层数必须小于100,所以如果你需要嵌套的层数大于这个数,请自行修改php.ini.同时值得一提的是,匿名函数中也可以像普通自定义函数那样使用static变量

  1. 如果你将类实例的变量关联到匿名函数,那么当你使用该变量访问匿名函数时,结果也许会令你失望
$obj = new StdClass();
$obj->func = function(){
    echo "hello";
};
//$obj->func(); // 会出错,因为php会去$obj的类中寻找func()方法,结果却是undefined method
// you have to do this instead:
$func = $obj->func;
$func();

// or:
call_user_func($obj->func);

// however, you might wanna check this out:
$array['func'] = function(){
    echo "hello";
};

$array['func'](); // it works! i discovered that just recently ;)
  1. 一段有意思的代码
    $fib = function($n) use(&$fib) {
        if($n == 0 || $n == 1) return 1;
        return $fib($n - 1) + $fib($n - 2);
    };

   echo $fib(2) . "\n"; // 2
   $lie = $fib;
   $fib = function(){die('error');};//rewrite $fib variable 
   echo $lie(5); // error   because $fib is referenced by closure

注意到$fib中使用到了use(&$fib),所以当$fib改了之后会继续影响$lie的输出,如果一不小心就掉进去了,认为$lie=$fib是引用,其实不然,可以添加一层外壳进行隔绝保护

$fib = call_user_func(function(){
   
    $fib = function($n) use(&$fib) {
        if($n == 0 || $n == 1) return 1;
        return $fib($n - 1) + $fib($n - 2);
    };
    return $fib;
});

echo $fib(2) . "\n";//2
$ok = $fib;

$fib = function(){die('error')};//rewrite $fib variable but don't referenced $fib used by closure
echo $ok(5);//result ok 

使用call_user_func之后,里面的$fib与外面的$fib的作用域范围就不一样了,对外部的$fib的修改将不会影响内部对$fib的引用,也不会对$lie造成任何影响,测试这段代码的时候我没有注意到&$fib导致以为匿名函数的赋值是引用行为,结果发现修改$lie后并不会对$fib造成影响,当即就崩了,还专门跑去看php内核匿名的实现,发现其是通过closure类和__invoke来实现的,并不会造成这样的结果,然后一字一字排查,才发现这个愚蠢的疏忽

  1. 你可以在类内使用匿名函数对private或者protected变量进行读写,在匿名函数中可以直接使用$this,不需要使用use($this)将$this传入进去,这样反而会发生error
class Scope
{
    protected $property = 'default';
    // or even
    // private $property = 'default';

    public function run()
    {
        $func = function() {
            $this->property = 'changed';
        };
        $func();
        var_dump($this->property);
    }
}

$scope = new Scope();
$scope->run(); // 输出 changed

相关文章

  • PHP手册之匿名函数

    前言 PHP手册系列文章,会挑选一些手册中有意思的评论进行翻译手册目录: 语言参考---函数---匿名函数参考详情...

  • PHP全栈学习笔记32

    php自定义函数之匿名函数所谓匿名,就是没有名字。匿名函数,也就是没有函数名的函数。 变量函数式的匿名函数 内部函...

  • PHP全栈学习笔记32

    php自定义函数之匿名函数所谓匿名,就是没有名字。匿名函数,也就是没有函数名的函数。 变量函数式的匿名函数 内部函...

  • php中的匿名函数和闭包

    php中的匿名函数和闭包(closure) 一:匿名函数 (在php5.3.0 或以上才能使用) php中的匿名函...

  • PHP参考手册

    PHP参考手册 PHP array() 函数 PHP array_change_key_case()函数 PHP ...

  • Python精简学习(九)

    Python精简学习之函数之匿名函数-匿名函数

  • Modern PHP : 闭包和匿名函数

    Modern PHP : 闭包和匿名函数

  • PHP代码审计-常见危险函数

    PHP代码执行函数 eval & assert & preg_replace eval 函数 php官方手册:ht...

  • PHP匿名函数

    匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名...

  • PHP匿名函数

    匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名...

网友评论

      本文标题:PHP手册之匿名函数

      本文链接:https://www.haomeiwen.com/subject/ezavqftx.html