【问题标题】:late static binding in PHPPHP中的后期静态绑定
【发布时间】:2012-04-21 01:43:26
【问题描述】:

我正在阅读有关 LSB 功能的 php 手册,我了解它在静态上下文中的工作原理,但我不太了解它在非静态上下文中的工作原理。手册中的例子是这样的:

<?php
class A {
    private function foo() {
        echo "success!\n";
    }
    public function test() {
        $this->foo();
        static::foo();
    }
}

class B extends A {
   /* foo() will be copied to B, hence its scope will still be A and
    * the call be successful */
}

class C extends A {
    private function foo() {
        /* original method is replaced; the scope of the new one is C */
    }
}

$b = new B();
$b->test();
$c = new C();
$c->test();   //fails
?>

输出是这样的:

success!
success!
success!


Fatal error:  Call to private method C::foo() from context 'A' in /tmp/test.php on line 9

我不明白B类,A中的私有方法如何继承给B?谁能带我了解这里发生了什么?非常感谢!

【问题讨论】:

  • 一般注意事项:您可能不应该使用:: 来调用非静态属性或方法。
  • @mc10 - static:: 是您在 PHP 5.3 中调用 late static binding 的方式。但我同意你应该为静态成员保留它。

标签: php late-static-binding


【解决方案1】:

使用后期静态绑定只会更改为调用选择的方法。一旦选择了方法,就会应用可见性规则来确定是否可以调用它。

对于BA::test 查找并调用A::fooB 中的评论不正确--foo 未复制到 B。由于它是私有的,因此只能从A 中的其他方法调用,例如A::test

C 失败,因为后期静态绑定机制定位到 new 私有方法 C::foo,但 A 的方法无权访问它。

我建议您为静态字段和方法保留后期静态绑定以避免混淆。

【讨论】:

  • 谢谢。但我不明白为什么 foo() 被 B 继承,因为它是私有的。你的意思是当$b->test()被执行的时候,这里的$b实际上是被当作A类的对象,还是应该是?
  • @Michael - 从技术上讲,A::foo 甚至没有被继承,因为它是私有的。关键是只有A的方法才能调用。
  • 没错,你不能像这样从父级调用子级的私有方法。
  • 好的,这就是我的解释。当 C 被实例化时,它本身没有 test(),但在父级 A 中找到上游,因此“$c->test()”的上下文实际上是 A。因此,$this->foo()解析为 A 中的 foo(),但 C::foo() 导致错误,因为该方法在 C 中被覆盖。是吗?
  • @Michael - 不能重写私有方法,因为从技术上讲它们不是继承的。它们对于声明它们的类是本地的,并且在外部是不可见的。 $c-&gt;test() 的上下文是类C。这就是 LSB 在 C 中查找名为 foo 的方法的原因。 LSB 绕过不适用于静态和私有方法的继承。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
相关资源
最近更新 更多