Почему PHP позволяет вызывать нестатический метод статически, используя Имена классов и по различным ключевым словам, таким как self, static & родитель, которые являются заполнителями для имен классов?
Но с другой стороны это не позволяет вызывать нестатические свойства
статически?
Вот пример кода —
<?php
# PHP Version 7.1.7
error_reporting(E_ALL);
ini_set('display_errors', 1);
class Fruit {
public $name = 'Fruit';
public function x() {
echo "Fruit_x" . "<br>";
}
}
class Orange extends Fruit {
public $name = 'Orange';
public function x() {
echo "Orange_x" . "<br>";
parent::x();
self::y();
static::z();
// Code Below will throu Uncaught Error: Access to undeclared static property
// echo parent::$name . "<br>";
// echo self::$name . "<br>";
}
public function y(){
echo "Y" . "<br>";
}
public function z(){
echo "Z" . "<br>";
}
}
(new Orange)->x(); // No Warnings
Orange::x(); // However calling like this shows warning as of PHP 5 & 7
// Docs - http://php.net/manual/en/language.oop5.static.php
?>
Вы можете запустить код в браузере, чтобы увидеть следующий результат
Исходя из вашего комментария, я считаю, что ваше недоразумение исходит из того, что вы думаете parent::
а также self::
всегда используются для совершения статических звонков.
Parent используется для доступа к родительскому методу любого типа, а self всегда используется для использования текущего метода класса. Поскольку методы могут быть определены только один раз, PHP может определить, как эти методы должны вызываться.
https://3v4l.org/NJOTK покажет пример разницы между $this->call()
, self::call()
, а также parent::call()
при использовании наследования. static::
разрешено, но функционально эквивалентно $this->
например методы.
Такое же поведение не распространяется на свойства. Свойства экземпляра не поддерживают одинаковый уровень наследования, они наследуют только значения при создании экземпляра. Вы не можете получить доступ к свойству родителя, для этого экземпляра существует только одно свойство. Таким образом, нестатические свойства всегда доступны с помощью $this->property
,
Других решений пока нет …