Доступ к некорректному статическому свойству из не статического метода в PHP
Я испытываю что-то в 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();
2 ответа
Это на самом деле не ошибка, но, скорее, это результат, который не описан в документации. Я провел небольшое исследование и сам поиграл с несколькими вещами, и я думаю, что понял это, но я не могу быть уверен на 100%, так как нет официального текста, охватывающего это.
Создается впечатление, что когда вы пытаетесь вызвать статический метод для экземпляра, это равносильно использованию имени класса, и PHP фактически будет вызывать его именно так, а не для экземпляра. Например $B::getWhy();
такой же как B::getWhy()
Это то, как основной код увидит это, независимо от того, передаете ли вы ему экземпляр или нет.
Проблема в том, что вы вызываете нестатический метод как статический метод. Из-за того, как методы работают, они требуют возможности для обеспечения таких вещей, как self
а также $this
, Теперь, вызывая нестатический метод, как если бы он был статическим, и учитывая вышеизложенное о том, как PHP будет фактически выполнять код, единственной доступной областью действия является область класса. A
потому что это та сфера, из которой вы его называете. Это означает, что позднее статическое связывание имеет место и переопределяет B::$why
с A::$why
из-за изменения области действия, что именно то, чего должна достичь поздняя статическая привязка.
Я надеюсь, что это имеет смысл, если есть какие-то неясные моменты, дайте мне знать, и я сделаю все возможное, чтобы объяснить.
Для получения дополнительной информации, есть еще один вопрос, который на самом деле решает это: вызов нестатического метода с "::"
$B::bah();
должно быть $B->bah();
, как bah
не является статической функцией