Разрешение имен классов PHP 5.5

В PHP 5.5 в качестве новой функции реализован новый способ получения имени класса с помощью синтаксиса ::class:

<?php

namespace Testing;

class Test{}

echo Test::class; // Testing\Test;

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

<?php

echo UndeclaredClass::class; // UndeclaredClass

В некоторых других случаях возникает ошибка, но не здесь. Кто-нибудь знает, с конкретным основанием, если возможно, почему это происходит?

Есть ли в нем что-то от Late Static Bindings или это просто (временное) ограничение/ошибка этой совершенно новой функции?


person Bruno Augusto    schedule 27.06.2014    source источник
comment
Интересный вопрос. Почему бы не спросить (или не обратиться к этой странице) в списке рассылки разработчиков PHP?   -  person Borislav Sabev    schedule 30.06.2014
comment
Вы поверите мне, если я скажу, что говорю, что не знаю, как?   -  person Bruno Augusto    schedule 30.06.2014
comment
Ну да, поскольку я знаю, насколько это сложно: bg2.php.net/contact.php bg2.php.net/support.php Ваш лучший и быстрый выбор — это список рассылки, поскольку там НЕТ ОФИЦИАЛЬНОГО IRC-канала. Пожалуйста, поделитесь ответом здесь после.   -  person Borislav Sabev    schedule 30.06.2014
comment
Это не воспроизводится для меня, <?php echo UndeclaredClass::class; всегда выдает ошибку для меня.   -  person Daniel W.    schedule 02.07.2014


Ответы (2)


Наконец-то официальный ответ... условно говоря. Он был представлен мне кем-то, идентифицированным как [email protected] в bu report я создал сегодня. Единственным исключением является то, насколько вовлечен этот человек в разработку PHP.

TL;DR

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

Режиссерская версия

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

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

Имя класса может быть либо абсолютным ("\Testing\Test"), либо относительным ("Test"), и если оно относительное, то это может быть обычное имя. [требуется дополнительный контекст]

namespace Testing {
    echo Test::class; // \Testing + Test = \Testing\Test
}

Или псевдоним:

use Testing\Test as AliasedTest;
echo AliasedTest::class; // AliasedTest + use = \Testing\Test

Без всего этого автозагрузка не работала бы!

::class — это просто новый инструмент для раскрытия информации, которую PHP всегда знал.

Этот «расширенный ответ» почти совпадает с тем, что я получил в отчете об ошибке. Причина столь очевидного копирования и вставки в том, что изначально я создал этот ответ для другого сообщества Stack Overflow.

person Bruno Augusto    schedule 30.06.2014
comment
Можете ли вы объяснить, почему echo UndeclaredClass::class; не выдает вам ошибку? - person Daniel W.; 02.07.2014
comment
Человек, который ответил на мой запрос в службу поддержки, объяснил мне, что имя класса получается до создания экземпляра самого объекта, и поэтому ошибка не возникает, поскольку класс не нужно загружать. - person Bruno Augusto; 02.07.2014
comment
Что ж, на самом деле это очень полезно — позволяет IDE обнаруживать опечатки во время разработки без потенциальных накладных расходов во время выполнения (подумайте о ленивой регистрации в контейнере IOC). Спасибо за официальное заявление - person Steve; 25.08.2015

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

<?php
namespace Testing;

class Test{
    public function abc()
    {
        echo "This is the ABC.";
    }
}

namespace Testing1;

class Test{
    public function abc()
    {
        echo "This is the ABC.";
    }
}
// echo Test::class; // Testing\Test;
$test =  new Test();

print_r(get_class($test));
// echo "<br>";
// echo UndeclaredClass::class;
?>
person Prem Kumar Maurya    schedule 30.07.2014
comment
Хотя я ценю ваш ответ, суть вопроса не в этом. Я не пытался получить имя класса. Вместо этого я пытался понять, почему такая функция не вызывает ошибку. - person Bruno Augusto; 30.07.2014