Когда используешь use
импортировать / псевдоним пространства имен в текущем пространстве имен в PHP — разрешено ли импортировать в имя класса, который существует в текущем пространстве имен, но не используется в текущем файле?
PHP 5.6 и 7.x, похоже, ведут себя по-разному. К сожалению, я не мог понять, разрешено ли это вообще. Если бы это было запрещено, я бы хотел, чтобы моя среда IDE обнаруживала такие коллизии (потому что код мог сломаться в любой момент снова), иначе это ошибка PHP в версии 5.6.
Посмотрите минимальный код, чтобы получить идею:
SRC / Главная / Bar.php:
namespace Cumuru\MinimalExample\Main;
class Bar { }
SRC / ToBeImported / Bar.php
namespace Cumuru\MinimalExample\ToBeImported;
class Bar { }
SRC / Главная / foo.php
namespace Cumuru\MinimalExample\Main;
use Cumuru\MinimalExample\ToBeImported\Bar;
class Foo { }
index.php
// [initialize autoloading]
// the following line breaks the code
$bar = new \Cumuru\MinimalExample\Main\Bar();
$foo = new \Cumuru\MinimalExample\Main\Foo();
Этот код сломается в PHP 5.6, в то время как в 7.1 он работает без сбоев. Сообщение об ошибке
PHP Fatal error: Cannot use Cumuru\MinimalExample\ToBeImported\Bar as Bar because the name is already in use in .../src/Main/Foo.php on line 4
PHP Stack trace:
PHP 1. {main}() .../index.php:0
PHP 2. spl_autoload_call() .../index.php:6
PHP 3. Composer\Autoload\ClassLoader->loadClass() .../index.php:6
PHP 4. Composer\Autoload\includeFile() .../vendor/composer/ClassLoader.php:322
Если вы хотите запустить код, посмотрите этот репозиторий github!
Мне очень повезло обнаружить ошибку перед ее развертыванием, это могло бы стоить мне целую вечность, чтобы найти ее в нашей производственной системе. Я отправил отчет об ошибке для своей IDE, но его приоритет был снижен, указав, что
ошибка в конкретной версии PHP, которая сейчас устарела
Интересно, правда ли это, или это просто деталь реализации PHP 7 для обработки импорта по каждому файлу, который может быть изменен в будущем (снова нарушая код).
Редактировать:
Я знаю о возможности псевдонимов имен классов через use Cumuru\MinimalExample\ToBeImported\Bar as ImportedBar;
,
Моя проблема в том, что происходит, если класс Cumuru\MinimalExample\Main\Bar
создается последним, при этом оба других класса остаются неизменными. Учебный класс Foo
будет роковым тогда — если и только если, класс Cumuru\MinimalExample\Main\Bar
был создан до учебный класс Foo
загружен (в том же запросе / процессе).
Задача ещё не решена.
Других решений пока нет …