【问题标题】:Unexpected scope of static anonymous function in PHPPHP中静态匿名函数的意外范围
【发布时间】:2015-02-07 18:36:49
【问题描述】:

我在 PHP5.6.2 中有以下代码。它有 FatherGuy extends FatherChild extends Guy 类。所有这些类都有一个静态方法hi,它输出类的名称:

class Father {
  static function hi() {
    echo "Father" . PHP_EOL;
  }
}

class Guy extends Father {

  static function hi() {
    echo "Guy" . PHP_EOL;
  }

  static function test() {
    self::hi();
    static::hi();
    parent::hi();
    $anon = function() {
      self::hi();  // shouldn't this call Guy::hi()?
      static::hi();
      parent::hi();  // shouldn't this call Father::hi()?
    };
    $anon();
  }

}

class Child extends Guy {
  static function hi() {
    echo "Child" . PHP_EOL;
  }
}

Child::test();

我期望的输出是:

Guy
Child
Father
Guy
Child
Father

前三行符合预期。但令人惊讶的是,最后三个是:

Child //shouldn't this call Guy::hi()?
Child
Father //shouldn't this call Father::hi()?

所以看起来匿名函数$anon的范围是Child。但是它不应该与调用它的方法具有相同的范围(即Guy)吗?


编辑 1: 另外,the specification 不会要求它按我的预期工作:

在实例或静态方法中定义的匿名函数的作用域设置为定义它的类。否则,匿名函数是无作用域的。


编辑 2: 请注意,当我从 Guy::test() 中删除 static 修饰符并像 (new Child)->test(); 一样调用它时,输出符合预期。


编辑 3: 在期待一些更奇怪的行为之后,我认为这是 PHP -> according bug report 中的一个实际错误

【问题讨论】:

  • 得到一个致命错误:如果我执行你的代码,当18
    行上没有活动的类范围时无法访问self::
  • @KarolyHorvath 我不希望 ::hi() 被打印,而是在另一个类上被调用(见编辑)
  • @Freez 我使用sandbox.onlinephpfunctions.com 使用 PHP 5.6.2 对其进行测试
  • @Freez 你用的是哪个 PHP 版本?
  • @MinecraftShamrock 我使用 5.3.3 进行测试(这就是问题所在;),您没有指定 PHP 的版本

标签: php static scope anonymous-function


【解决方案1】:

Child 继承了函数 test(),所以匿名函数的作用域是 Child,即“定义它的类”。

【讨论】:

  • 对于Guy::test() 不是静态的情况,不能说完全相同的事情吗?在这种情况下,即使通过 Child 调用,它仍将作为“定义在”Guy 中处理。
  • 如果 Guy::test() 不是静态的,那么它就不是“在实例或静态方法中定义的”。但是你很难把所有的来龙去脉都弄清楚。
  • 您能否分享一个来自 php.net 手册或指定此内容的 php github 规范的链接?只是为了让我能从根本上学习。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 2017-07-13
  • 2011-02-13
  • 2015-09-20
相关资源
最近更新 更多