0

I am experiencing something in PHP that seems very odd. I am trying to access a static property from a non static method. I need to use the static keyword to access this property as it can have different values in each child class.

However, instead of accessing a property from the expected class at all, it instead accesses the property from the calling class. This seems like a bug to me, but if it isn't, I was wondering if someone could explain this behaviour to me and also explain how I can access this static property.

My expectation here is that the static property $why would be taken from class B. I am perplexed as to why instead it would be taken from Class 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();
4

2 回答 2

2

$B::bah();应该是$B->bah();,因为bah不是静态函数。

于 2013-12-17T19:29:36.933 回答
2

这并不是一个真正的错误,但更多的是文档中没有真正涵盖的结果。我自己做了一些研究并玩了一些东西,我想我已经弄清楚了,但我不能 100% 确定,因为没有官方文本涵盖这一点。

我得到的印象是,当您尝试在实例上调用静态方法时,它等同于使用类名,而 PHP 实际上会以这种方式调用它,而不是实例。例如$B::getWhy();与 相同B::getWhy(),这是核心代码将如何看待它,无论您是否将其传递给实例。

您遇到的问题是您将非静态方法作为静态方法调用。由于方法的工作方式,它们需要一个范围来提供诸如self和之类的东西$this。现在,通过调用非静态方法,就好像它是一个静态方法一样,并考虑到上面关于 PHP 实际运行代码的方式,唯一可用的范围是类,A因为那是你的范围从调用它。这意味着后期静态绑定发生并覆盖B::$whyA::$why因为范围更改,这正是后期静态绑定应该实现的。

我希望这是有道理的,如果有任何不清楚的地方,请告诉我,我会尽力解释。

有关更多信息,还有另一个问题实际上解决了这个问题:Calling non static method with "::"

于 2013-12-17T19:33:25.113 回答