【问题标题】:PHP closure scope problemPHP闭包范围问题
【发布时间】:2011-09-26 11:17:25
【问题描述】:

显然 $pid 超出了这里的范围。它不应该与功能一起“关闭”吗?例如,我很确定这就是闭包在 javascript 中的工作方式。

根据php closures are broken的一些文章,所以我无法访问这个

那么如何从这个闭包函数中访问$pid呢?

class MyClass {
  static function getHdvdsCol($pid) {
    $col = new PointColumn();
    $col->key = $pid;
    $col->parser = function($row) {
        print $pid; // Undefined variable: pid
    };
    return $col;
  }
}

$func = MyClass::getHdvdsCol(45);
call_user_func($func, $row);

编辑我已经解决了这个问题:$col->parser = function($row) use($pid)。但是我觉得这很难看。

【问题讨论】:

  • 这并不难看,它是闭包在 php 中的工作方式
  • 在 php 中就是这样......
  • 这是一种丑陋的语言,但我坚持使用它。 :(
  • 一天比一天丑。 (:
  • 从 PHP 5.4 开始,您可以在闭包内访问 $this

标签: php scope closures


【解决方案1】:

你需要用这种方式指定哪些变量应该被关闭:

function($row) use ($pid) { ... }

【讨论】:

  • 如果这个闭包保存在一个变量中,然后传递到另一个 $pid 不存在的作用域,pid 会以某种方式被包裹在闭包中,还是无法访问?
  • @Josh Nankin:实际上use($var,...) 是在 php 中实现闭包的方式。因此,如果您将匿名函数传递给另一个变量范围 - $pid 变量将包含最后定义的值。
  • 这个“使用”的东西是不是感觉很奇怪,还是只是我?在使用其他语言的闭包后,我无法克服它。 ://
  • @Matjaz Muhic:是的,这对每个人来说都很奇怪,不仅仅是你
【解决方案2】:

您可以使用 bindTo 方法。

class MyClass {
  static function getHdvdsCol($pid) {
    $col = new PointColumn();
    $col->key = $pid;
    $parser = function($row) {
        print $this->key;
    };
    $col->parser = $parser->bindTo($parser, $parser);
    return $col;
  }
}

$func = MyClass::getHdvdsCol(45);
call_user_func($func, $row);

【讨论】:

    【解决方案3】:

    我认为 PHP 在变量范围方面非常一致。规则是,如果在函数外部定义变量,则必须显式指定它。词法范围使用“use”,全局使用“global”。

    例如,你也不能直接使用全局变量:

    $n = 5;
    
    function f()
    {
        echo $n; // Undefined variable
    }
    

    您必须使用全局关键字:

    $n = 5;
    
    function f()
    {
        global $n;
        echo $n;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-02-17
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      • 2010-11-05
      • 1970-01-01
      相关资源
      最近更新 更多