Что происходит здесь, в PHP с классами?

Если у меня есть этот код, строка «test» будет эхом. Это в PHP 5.3. Это какой-то надзор, на который нельзя положиться, или это какой-то способ добиться множественного наследования в PHP?

class Test1 { function getName() { return $this->name; } } class Test2 { public $name = 'test'; function getName() { return Test1::getName(); } } $test = new Test2; echo $test->getName(); 

РЕДАКТИРОВАТЬ:

Как было указано в комментариях GZipp, это фактически документированное поведение. См. Эту страницу: http://us2.php.net/manual/en/language.oop5.basic.php и заголовок «Пример # 2 Некоторые примеры $ this псевдо-переменной».

Классы A и B имеют аналогичное отношение к моим двум тестовым классам выше и линиям

 $b = new B(); $b->bar(); 

Покажите более или менее тот же результат, что и в моем примере.

Чтобы быть ясным – это не наследование. Test2 не расширяет Test1. Вы статически ссылаетесь на общедоступный метод класса Test1.

Тем не менее, факт, что он возвращает «тест», интересен, мягко говоря. И я вижу, где это дает идею наследования.

Если вы не можете найти достойный ответ, я бы отправил ваш код как ошибку.

ОБНОВИТЬ

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

 class Test1 { function getName() { echo get_class($this); return $this->name; } } // ... $test = new Test2; echo $test->getName(); // echoes 'Test2 test' 

PHP позволяет вызывать нестатические методы, как если бы они были статическими, – это функция. PHP передает $this как неявный параметр для таких вызовов. Как и при вызове метода обычный способ.

Но, очевидно, PHP не проверяет, наследует ли статически называемый класс текущий, и это ошибка.

Вот как вы могли бы думать о том, что делает PHP:

 function Test1->getName($this = null) { return $this->name; } function Test2->getName($this = null) { return Test1->getName($this); } $test = new Test2; echo $test->getName($test); 

Такое поведение неверно. Правильный Test2->getName будет:

 function Test2->getName($this = null) { return $this instanceof Test1 ? Test1->getName($this) : Test1->getName(); } 

Это должно быть ошибкой. 100%.

  1. Это не наследование.
  2. Вы не должны иметь возможность вызывать Test1 :: getName (), поскольку getName () в Test1 не является статическим
  3. Даже если вы могли бы назвать это, имя $ this-> не должно иметь доступ к значению в Test2.

Это нарушает так много правил OO. Я серьезно озадачился, как это прошло через тестирование. Хорошо, не нахожу это!