Пространства имен - это один из способов инкапсуляции элементов. Такое абстрактное понятие можно увидеть во многих местах. Например, в любой операционной системе директории служат для группировки связанных файлов и выступают в качестве пространства имен для находящихся в них файлов. В качестве конкретного примера файл foo.txt может находиться сразу в обеих директориях: /home/greg и /home/other, но две копии foo.txt не могут существовать в одной директории. Кроме того, для доступа к foo.txt извне директории /home/greg, мы должны добавить имя директории перед именем файла используя разделитель, чтобы получить /home/greg/foo.txt. Этот же принцип распространяется и на пространства имен в программировании.
Пространства имен PHP предоставляют возможность группировать логически связанные классы, интерфейсы, функции и константы.
Определение пространства имен с помощью ключевого слова namespace.
namespace MyProject; //объявление пространства имен должно быть первым выражением в скрипте
class Connection { /* ... */ }
function connect() { /* ... */ }
Определение подпространства имен с иерархией.
namespace MyProject\Sub\Level; 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() { /* ... */ } }
PHP-код не может находиться вне скобок конструкции пространства имен, кроме начального выражения declare.
declare(encoding='UTF-8'); namespace MyProject { const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ } } namespace { // глобальный код session_start(); $a = MyProject\connect(); echo MyProject\Connection::start(); }
Поимо ключевого слова namespace, в PHP имеется магическая константа __NAMESPACE__
namespace MyProject; echo '"', __NAMESPACE__, '"'; // выводит "MyProject"
Использование константы __NAMESPACE__ в глобальном пространстве.
echo '"', __NAMESPACE__, '"'; // выводит ""
Использование константы __NAMESPACE__ для динамического конструирования имени
namespace MyProject; function get($classname) { $a = __NAMESPACE__ . '\\' . $classname; return new $a; }
Возможность ссылаться на внешнее абсолютное имя по псевдониму или импортированию - это важная особенность пространств имен. Это похоже на возможность файловых систем unix создавать символические ссылки на файл или директорию.
Все версии PHP, поддерживающие пространства имен, поддерживают три вида создания псевдонима имени или импорта: создание псевдонима для имени класса, создание псевдонима для имени интерфейса и для имени пространства имен. PHP 5.6+ также поддерживает импорт функций и имен констант.
В PHP создание псевдонима имени выполняется с помощью оператора use. Вот пример, показывающий 5 типов импорта:
namespace foo; use My\Full\Classname as Another; // это тоже самое, что и использование My\Full\NSname as NSname use My\Full\NSname; // импортирование глобального класса use ArrayObject; // импортирование функции (PHP 5.6+) use function My\Full\functionName; // псевдоним функции (PHP 5.6+) use function My\Full\functionName as func; // импортирование константы (PHP 5.6+) use const My\Full\CONSTANT; $obj = new namespace\Another; // создает экземпляр класса foo\Another $obj = new Another; // создает объект класса My\Full\Classname NSname\subns\func(); // вызывает функцию My\Full\NSname\subns\func $a = new ArrayObject(array(1)); // создает объект класса ArrayObject // без выражения "use ArrayObject" мы создадим объект класса foo\ArrayObject func(); // вызывает функцию My\Full\functionName echo CONSTANT; // выводит содержимое константы My\Full\CONSTANT
Импорт/создание псевдонима имени с помощью оператора use, комбинирование нескольких операторов use
use My\Full\Classname as Another, My\Full\NSname; $obj = new Another; // создает объект класса My\Full\Classname NSname\subns\func(); // вызывает функцию My\Full\NSname\subns\func
Начиная с PHP 7.0, классы, функции и константы, импортируемые из одного и того же namespace, могут группироваться в одном операторе use.
// Код до PHP 7 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; // Код на PHP 7+ 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};
Имена классов всегда преобразуются к текущему имени пространства имен. Таким образом, чтобы получить доступ ко внутреннему классу или пользовательскому классу вне пространства имен, необходимо ссылаться по их абсолютному имени. Например:
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 не найден