Что здесь происходит в PHP с классами? - PullRequest
7 голосов
/ 02 октября 2010

Если у меня есть этот код, выводится строка «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();

EDIT:

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

Классы A и B имеют схожую связь с моими двумя тестовыми классами выше и строками

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

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

Ответы [ 3 ]

1 голос
/ 02 октября 2010

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();
}
1 голос
/ 02 октября 2010

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

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

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

UPDATE

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

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

// echoes 'Test2 test'
0 голосов
/ 02 октября 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...