почему ключевое слово $ дает фатальную ошибку со статическим, но (новый self) работает нормально

class A {
public $a = "BooMBa";

public function fun1() {
echo $this->a;
// echo (new self)->a;
}
}

class B extends A {

public static function fun2() {
return (new self)->fun1();
// return static::fun1();
}
}

B::fun2();  // returns BooMBa

Если я изменю fun2 () на return static::fun1() тогда это дает

«Неустранимая ошибка: использование $ this, когда не в контексте объекта»

Но если я изменю fun1 на echo (new self)->a; тогда работает нормально.
Может кто-нибудь объяснить, почему static:: ненавидеть $this но нет (new self),

PS: пожалуйста, учтите, что я прошел через это ниже, учитывая Q&Разделы и еще несколько статей пока не могут точно понять, что именно происходит.
Что делает новое Я (); значит в PHP?
PHP: разница ч / б новый я и новый объект ()
PHP: руководство по основам
в PHP, в чем разница между self и $ this?

PPS: это Q& Неустранимая ошибка PHP: использование $ this, когда оно не в контексте объекта не имеет ничего общего с моим, кроме того же сообщения об ошибке. Это совершенно другой контекст. В этом вопросе он просто статически вызывает нестатический метод. Между тем, мой вопрос более сложен с поздними статическими привязками и ключевыми словами (новая личность). Я не могу понять мою проблему с ответом в вышеупомянутом вопросе.&А так, пожалуйста, пройдите оба Q&А перед пометкой дублируй. Спасибо.

0

Решение

Этот вопрос приходит к вопросу «в чем разница между классом и экземпляром».

Я упросту ваш пример и пойду шаг за шагом.

class A {
public $a = "BooMBa";
public function fun1() {
echo $this->a;
}
public static function fun2() {
return (new self)->fun1();
}
}
A::fun2();  // returns BooMBa
  1. A::func2() — статический вызов A::func2
  2. (new self)->fun1() — создает экземпляр A и звонки fun1 этого экземпляра
  3. echo $this->a — эхо содержимое a текущего (созданного в шаге 2) экземпляра

Каждый звонок A::func2 создает новый экземпляр A на шаге 2


class A {
public $a = "BooMBa";
public function fun1() {
echo $this->a;
}
public static function fun2() {
return static::fun1();
}
}
A::fun2();  // fails
  1. A::func2() — статический вызов A::func2
  2. static::fun1() — статический вызов A::func1, нет экземпляра. AFAIK это должно генерировать предупреждение, так как вы делаете статический вызов метода экземпляра
  3. echo $this->a; — эхо содержимое a текущего экземпляра, но нет экземпляра, так как мы пришли сюда из статического вызова, мы находимся в области видимости класса. ошибка

class A {
public $a = "BooMBa";
public function fun1() {
echo (new self)->a;
}
public static function fun2() {
return static::fun1();
}
}
A::fun2();  // returns BooMBa
  1. A::func2() — статический вызов A::func2
  2. static::fun1() — статический вызов A::func1нет экземпляра
  3. echo (new self)->a — создать новый экземпляр A и эхо содержимое переменной a только что созданного экземпляра

Каждый звонок A::func2 создает новый экземпляр A на шаге 3


class A {
public $a = "BooMBa";
public function fun1() {
echo $this->a;
}
public function fun2() {
return $this->fun1();
}
}
$a = new A();
$a->fun2();  // returns BooMBa
  1. $a = new A() — создать новый экземпляр A
  2. $a->fun2() — вызов метода fun2 например $a
  3. $this->fun1() — вызов метода fun1 текущего экземпляра ($a)
  4. echo $this->a — эхо содержимое a текущего экземпляра ($a)

$this ссылается на текущий экземпляр класса, но если вы static звоните, экземпляра нет.
new self создает новый экземпляр класса, который позволяет использовать $this так как у вас есть экземпляр, чтобы сослаться на


Давайте сделаем пример на кошках. Экземпляр Cat это какой-то $cat который стоит перед вами. Вы можете задать свой $cat в purrr и так как вы ссылаетесь на конкретный экземпляр cat, внутри метода purrr этой кошки вы можете обратиться к $this и позвонить echo $this->purrrSound,
Когда вы делаете статический вызов, вы делаете вызов абстрактной концепции Catнет конкретного случая Cat и нет $this ссылаясь на.

class Cat {
public $purrrSound = "purrrrr...";
public function purrr() {
echo $this->purrrSound;
}
}
$cat = new Cat();
$cat->purrr(); // kittty purrrr, please?
// Cat::purrr(); // all the Cats in the universe, purrr now?
1

Другие решения

Статический контекст

В PHP вы можете вызывать метод статически с помощью оператора Scope Resolution Operator. ::, Итак, это выражение просто статический вызов:

return static::fun1()

Когда вы находитесь в статическом контексте (после статического вызова) $this не работает — это утверждение языка. Даже в статическом контексте это выражение остается в силе:

(new self)->a

Просто потому, что вы создаете новый экземпляр объекта, а затем получаете его публичную собственность.


Устаревшее примечание:

В PHP 5 вызов нестатических методов статически генерирует
Предупреждение об уровне E_STRICT.

Предупреждение В PHP 7 статические вызовы нестатических методов не рекомендуется,
и сгенерирует предупреждение E_DEPRECATED. Поддержка звонков
нестатические методы статически могут быть удалены в будущем.

На ваш взгляд:

Не используйте статические методы, потому что это соединение для других классов, и обычно это просто процедурный код, закрываемый в статическом методе. Например, реализуйте эту функцию в новом классе и используйте внедрение зависимостей, если вам это нужно.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector