Пространство имен

Пространства имён в PHP позволяют избежать конфликта имён и сгруппировать функционал. Внутри пространства имён могут быть размещены классы, интерфейсы, функции и константы

    Пространство имен

    Foo - неполное имя
    Foo\Bar - полное имя
    \Foo\Bar - абсолютное имя
    namespace\Foo\Bar - относительное имя


    Абсолютные имена разрешаются в имя без ведущего разделителя пространства имён. Например, \A\B разрешается в A\B
    Относительные имена разрешаются в имя с заменой ключевого слова namespace текущим пространством имён. Если имя встречается в глобальном пространстве имён, префикс namespace\ удаляется. Например, имя namespace\A внутри пространства имён X\Y разрешается в X\Y\A. То же имя в глобальном пространстве имён разрешается в A.
    В полных именах первый сегмент имени преобразовывается с учётом текущей таблицы импорта класса или пространства имён. Например, если пространство имён A\B\C импортировано как C, то имя C\D\E преобразуется в A\B\C\D\E
    В полных именах, если не применялось правило импорта, текущее пространство имён добавляется к имени. Например, имя C\D\E внутри пространства имён A\B разрешится в A\B\C\D\E
    Неполные имена преобразовываются с учётом текущей таблицы импорта и типа элемента. То есть имена как у классов преобразовываются с учётом таблицы импорта классов или пространств имён, имена функций — с учётом таблицы импорта функций, а константы — таблицы импорта констант. Например, при записи use A\B\C;, вызов new C() разрешается в A\B\C(). Аналогично, при записи use function A\B\foo; вызов foo() разрешается в A\B\foo
    В начало неполных имён, если не применялось правило импорта и имя относится к элементу с именем как у класса, добавляется текущее пространство имён. Например, имя класса в выражении new C() внутри пространства имён A\B разрешится в имя A\B\C
    В неполных именах, если не применялось правило импорта и имя относится к функции или константе, а код лежит за пределами глобального пространства имён, имя разрешается при выполнении. Вот как разрешится вызов функции foo() в коде в пространстве имён A\B:
    Выполняется поиск функции из текущего пространства имён: A\B\foo()
    PHP пытается найти и вызвать функцию foo() из глобального пространства имён
    Подробные примеры в источнике: https://www.php.net/manual/ru/language.namespaces.rules.php

    Пространство имен - способ инкапсуляции объектов, подобно тому как директории инкапсулируют файлы
    С помощью пространств имен устраняют конфликты между кодом и внутренними или внешними классами, функциями и константами
    С помощью пространств имен можно создавать псевдонимы для длинных имен с целью улучшить читаемость кода
    Пространства имен помогают сгруппировать логически связанные классы, интерфейсы, функции, константы
    Замечание: Имена пространств имён регистронезависимы

    namespace mySpace; class MyClass { function MyFunc() { echo "MyFunc<br>"; } } function MyFunc() { echo "MyFunc"; } const MYCONST = 1; $a = new MyClass; $a->MyFunc(); $b = new \mySpace\MyClass; $b->MyFunc();


    Пространства имён в файлах объявляют в начале, перед любым другим кодом, кроме зарезервированного слова declare
    Только выражение declare разрешено помещать перед объявлением пространства имён, чтобы определить кодировку исходного файла. В дополнение, никакой код, кроме PHP-кода, нельзя размещать перед объявлением пространства имён, включая лишние пробелы
    Одно и то же пространство имён, в отличие от остальных конструкций PHP, допустимо определять в нескольких файлах, что помогает распределять содержание файлов по файловой системе
    Так же как файлы и каталоги, пространства имён PHP разрешают создавать иерархию имён. Поэтому имя пространства разрешено определять с подуровнями:
    namespace MyProject\Sub\Level;
    В одном файле разрешено объявлять несколько пространств имён. Есть два разрешённых синтаксиса:

    namespace MyProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } namespace AnotherProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ }

    Вместо него лучше пользоваться альтернативным синтаксисом со скобками

    namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace AnotherProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } }

    Практика написания кода настоятельно не рекомендует объединять пространства имён в одном файле
    Для объединения кода в глобальном пространстве имён с кодом в других пространствах имён пользуются только синтаксисом со скобками. Глобальный код должен быть помещён в конструкцию описания пространства имён без указания имени

    namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace { // Глобальный код session_start(); $a = MyProject\connect(); echo MyProject\Connection::start(); }

    Никакой PHP-код нельзя размещать за пределами скобок пространства имён, кроме начального выражения declare

    declare(encoding='UTF-8'); namespace MyProject { ... #test1.php namespace Foo\Bar\subnamespace; function foo() { echo "Foo\Bar\subnamespace<br>";} #test.php namespace Foo\Bar; include "test1.php"; function bar() { echo "Foo\Bar<br>";} bar(); #Foo\Bar subnamespace\foo(); #Foo\Bar\subnamespace \Foo\Bar\bar(); #Foo\Bar \Foo\Bar\subnamespace\foo(); #Foo\Bar\subnamespace namespace namespacename; class classname { function __construct() { echo __METHOD__,"<br>"; } } $obj = new \namespacename\classname; # namespacename\classname::__construct
    __METHOD__

    Выводит название метода
    function __construct() { echo __METHOD__,"\n"; }

    Выводит название функции

    function funcname() { echo __FUNCTION__,"\n"; }
    Псевдонимирование и импорт

    PHP умеет ссылаться на внешнее абсолютное имя по псевдониму или импортировать константы, функции, классы, интерфейсы, трейты, перечисления и пространства имен
    Псевдоним имени создается с помощью ключевого слова use
    Ключевое слово use должно быть указано в самом начале файла (в глобальной области) или внутри объявления пространства имён. Это нужно, потому что импорт выполняется во время компиляции, а не во время исполнения, поэтому его нельзя ограничить блоком кода
    Правила импорта задают на каждый файл отдельно. Поэтому присоединяемые файлы НЕ будут наследовать правила импорта из родительского файла

    #Это пространство которое включает в себя все что ниже namespace foo; use My\Full\Classname as Another, My\Full\MyName; #Далее к My\Full\Classname можно обращать по псевдониму Another $obj = new Another; // Создаёт объект класса My\Full\Classname use My\Full\NSname; #Импорт глобального объекта use ArrayObject; #Импортирование функции use function My\Full\functionName; #Создание псевдонима функции use function My\Full\functionName as func; #Импорт константы use const My\Full\CONSTANT; #Создает объект класса My\Full\Classname $obj = new Another; #Вызывает функцию My\Full\NSname\subns\func NSname\subns\func(); #Создаёт объект класса ArrayObject #без выражения use ArrayObject был бы создан объект класса foo\ArrayObject $a = new ArrayObject(array(1)); #вызывает функцию My\Full\functionName func(); #выводит содержимое константы My\Full\CONSTANT echo CONSTANT; #Создаёт экземпляр класса foo\Another $obj = new namespace\Another; MyName\subns\func(); // Вызывает функцию My\Full\MyName\subns\func $obj = new Another; // Создаёт объект класса My\Full\Classname #импорт распространяется только на неполные и полные имена #На абсолютные имена операция импорта не влияет $obj = new \Another; // Создаёт объект класса Another $obj = new Another\thing; // Создаёт объект класса My\Full\Classname\thing $obj = new \Another\thing; // Создаёт объект класса Another\thing

    Классы, функции и константы, импортируемые из одного и того же пространства имён (namespace), разрешено группировать в одном выражении с ключевым словом use

    use some\namespace\ClassA; use some\namespace\ClassB; use some\namespace\ClassC as C; use function some\namespace\fn_a; use function some\namespace\fn_b; use function some\namespace\fn_c; use const some\namespace\ConstA; use const some\namespace\ConstB; use const some\namespace\ConstC; // Эквивалентно следующему групповому объявлению с ключевым словом use use some\namespace\{ClassA, ClassB, ClassC as C}; use function some\namespace\{fn_a, fn_b, fn_c}; use const some\namespace\{ConstA, ConstB, ConstC};
    Возврат к глобальному пространству

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

    namespace A\B\C; const E_ERROR = 45; function strlen($str) { return \strlen($str) - 1; } echo E_ERROR, "\n"; // Выводит 45 echo INI_ALL, "\n"; // Выводит «7» — возвращается к глобальной константе INI_ALL echo strlen('hi'), "\n"; // Выводит «1» namespace A\B\C; class Exception extends \Exception {} $a = new Exception('hi'); // Переменная $a — это объект класса A\B\C\Exception $b = new \Exception('hi'); // Переменная $b — это объект класса Exception $c = new ArrayObject; // Фатальная ошибка, класс A\B\C\ArrayObject не найден
    Источники
    Последнее изменение: 20.11.2024 07:24


    Связанные темы
    Здесь пока нет комментариев
    Добавлять комментарии могут только авторизованные пользователи

    Авторизоваться
    Я буду рекламой
    Я тоже буду рекламой
    И я
    ВВЕРХ