Я натолкнулся на очень странное поведение на PHP5.4 (также присутствует в 5.5). В принципе, я вызываю нестатический метод статически, и я не получаю ошибку E_STRICT, где я определенно должен ее получить.
<?php error_reporting(E_ALL); class A { public function iAmNotStatic() {} }
Теперь, если я это сделаю:
A::iAmNotStatic();
Затем я получаю ошибку, как ожидалось. Strict standards: Non-static method A::iAmNotStatic() should not be called statically
.
А также, если я делаю вызов из контекста объекта, я также получаю ту же ошибку (как и ожидалось)
class B { public function __construct() { A::iAmNotStatic(); } } $b = new B(); // error here, as expected
Однако, если я это сделаю (назначьте A родителем B):
class B extends A { public function __construct() { A::iAmNotStatic(); } } $b = new B(); // no error
Затем PHP решает, что «нет проблем, у меня есть объект ($ b) с тем же родительским классом (A), давайте просто сделаем его контекстом для iAmNotStatic
».
Итак, является ли это признаком или ошибкой, и какова может быть цель этого запутанного поведения (недокументированного?)? Благодаря 🙂
В первом случае у вас нет объектного контекста, поскольку вы вызываете свой нестатический метод из внешнего пространства. Но во втором случае у вас есть контекст объекта, поскольку $this
будет ссылаться на экземпляр B
– и, следовательно, PHP обнаружит, что существует контекст объекта, и, следовательно, это нестатический вызов нестатического метода (все ОК). Если вы сомневаетесь в вызове через ::
– тогда, я думаю, вы должны напомнить, что, например, parent::method()
является действительным вызовом. Т.е. ссылка здесь не проблема.
Чтобы быть более конкретным:
class A { public function foo() { echo('foo called, class: '. get_class($this).PHP_EOL); } } class B extends A { public function __construct() { A::foo(); } } $b=new B(); //foo called, class: B
поэтому вы увидите класс B
как ожидалось, так как foo()
был унаследован.