代码之家  ›  专栏  ›  技术社区  ›  aefxx

是否可以在PHP5.2.x中不使用全局变量来模拟闭包?

  •  9
  • aefxx  · 技术社区  · 16 年前

    是否可以在PHP5.2.x中不使用全局变量来模拟闭包?我可以想出一种方法,将所需的变量作为额外参数传递给闭包,但这并不是最佳实践。

    有什么想法吗?

    4 回复  |  直到 16 年前
        1
  •  8
  •   Gordon Haim Evgi    16 年前

    有趣的问题。我得说 ,但让我们看看

    IBM - What's new in PHP5.3, Part 2

    闭包是在自己的环境中进行计算的函数,它有一个或多个绑定变量,在调用该函数时可以访问这些变量。

    还有(我的重点)

    要导入的变量 按值传递 ,这意味着如果我们更新闭包函数定义中传递的值,它将不会更新外部值。

    使用 global & use 条款,它已经偏离了5.3默认行为。

    $var = 'yes';
    $fn  = create_function('', 'global $var; $var = "no";');
    $fn();
    echo $var; // outputs no
    

    $var = 'yes';
    $fn  = create_function('', 'global $var; $tmp = $var; $tmp = "no";');
    $fn();
    echo $var; // outputs yes
    

    此外,全局变量的值(使用 create_function )在创建函数时,但在运行函数时,不会计算(绑定)

    $var = 'yes';
    $fn  = create_function('', 'global $var; $tmp = $var; return $tmp;');
    $var = 'maybe';
    echo $fn(); // outputs maybe
    
    $var = 'yes';
    $fn  = function() use ($var) { return $var; };
    $var = 'maybe';
    echo $fn(); // outputs yes
    

    同样重要的是

    *虽然我认为这是在最后的PHP5.3中删除的

    这是不可能的 全球的 关键字,您也不能只使用 $this 创建函数

    class A {
    
        protected $prop = 'it works';
    
        public function test()
        {
            $fn = create_function('', 'echo $this->prop;');
            return $fn;
        }
    }
    
    $a = new A;
    $fn = $a->test();
    $fn();
    

    将导致

    Fatal error: Using $this when not in object context
    

    总而言之
    创建函数 但是在执行创建的函数时导入,我想争论一下 此限制使闭包成为lambda


        4
  •  1
  •   newacct    14 年前

    在一些特殊情况下,你可以这样做。

    如果需要通过值(而不是引用)捕获变量,并且值是简单的值类型,如数字、字符串或上述数组(而不是引用类型,如对象、资源和函数),则可以使用 var_export()

    $var = array(1, 3);
    $f = create_function('',
        '$var=' . var_export($var,true) . '; return $var;');
    

    如果需要通过引用捕获变量,以便在函数调用中保持可变状态,但不需要在创建变量的原始范围中反映更改(例如,创建累加器,但对总和的更改不需要在创建范围中更改总和变量),然后可以类似地插入它,但作为静态变量:

    function make_accumulator($sum) {
        $f = create_function('$x',
            'static $var=' . var_export($var,true) . '; return $var += $x;');
        return $f;
    }