我在PHP中遇到的东西看起来很奇怪。我试图从非静态方法访问静态属性。我需要使用static关键字来访问此属性,因为它可以在每个子类中具有不同的值。
但是,它不是从期望的类中访问属性,而是从调用类访问该属性。这对我来说似乎是一个错误,但如果不是,我想知道是否有人可以向我解释这种行为,并解释我如何访问这个静态属性。
我的期望是静态属性$ why将从B类中获取。我很困惑为什么它会从A类中获取。
<?php
error_reporting(E_ALL & ~E_STRICT);
class A
{
public static $why = "Really don't want this value. Bug?";
public function callB()
{
$B = new B;
$B::getWhy(); // PHP Bug?
$B->getWhy();
$B::getWhyStatic();
$B::getWhyStaticSelf();
}
}
class Base {
protected static $why = "Don't want this value";
public static function getWhyStatic()
{
echo static::$why . "<BR>\n";
}
public static function getWhyStaticSelf()
{
echo self::$why . "<BR>\n";
}
public function getWhy()
{
echo static::$why . "<BR>\n";
}
}
class B extends Base
{
protected static $why = "Want this value?";
}
$A = new A;
$A->callB();
答案 0 :(得分:2)
$B::bah();
应为$B->bah();
,因为bah
不是静态函数。
答案 1 :(得分:2)
这不是一个真正的错误,但更多的结果并没有真正涵盖在文档中。我做了一些研究并且自己玩了一些东西,我想我已经弄清楚了,但我不能100%肯定,因为没有正式的文字涵盖这个。
我得到的印象是,当你试图在一个实例上调用静态方法时,它是使用类名的等价物,而PHP实际上会以这种方式调用它,而不是实例。例如,$B::getWhy();
与B::getWhy()
相同,核心代码将如何看待它,无论您是否将实例传递给它。
您遇到的问题是您将非静态方法称为静态方法。由于方法的工作方式,它们需要一个范围来提供self
和$this
等内容。现在,通过调用非静态方法就好像它是一个静态方法,并考虑上面关于PHP实际运行代码的方式,唯一可用的范围是类A
,因为那是您调用它的范围。这意味着后期静态绑定发生并覆盖B::$why
和A::$why
,因为范围发生了变化,这正是后期静态绑定应该实现的目的。
我希望这是有道理的,如果有任何不清楚的地方,请告诉我,我会尽力解释。
有关更多信息,还有另一个问题实际解决了这个问题:Calling non static method with "::"