diff --git a/language/namespaces.xml b/language/namespaces.xml new file mode 100644 index 000000000..095a65d87 --- /dev/null +++ b/language/namespaces.xml @@ -0,0 +1,1567 @@ + + + + + + + + + + Пространства имен + + Обзор пространств имен + + + Что такое пространства имен? В широком смысле - это один из способов инкапсуляции элементов. + Такое абстрактное понятие можно увидеть во многих местах. Например, в любой операционной + системе директории служат для группировки связанных файлов и выступают в качестве + пространства имен для находящихся в них файлов. В качестве конкретного примера файл + foo.txt может находиться сразу в обоих директориях: /home/greg + и /home/other, но две копии foo.txt не могут + существовать в одной директории. Кроме того, для доступа к foo.txt извне + директории /home/greg, мы должны добавить имя директории перед именем файла + используя разделитель, чтобы получить /home/greg/foo.txt. Этот же принцип + распространяется и на пространства имен в программировании. + + + В PHP пространства имен используются для решения двух проблем, с которыми + сталкиваются авторы библиотек и приложений при создании повторно используемых + элементов кода, таких как классы и функции: + + + + + + Конфликт имен между вашим кодом и + внутренними классами/функциями/константами PHP или сторонними. + + + + + Возможность создавать псевдонимы (или сокращения) для Ну_Очень_Длинных_Имен, чтобы облегчить + первую проблему и улучшить читаемость исходного кода. + + + + + + Пространства имен PHP предоставляют возможность группировать логически связанные + классы, интерфейсы, функции и константы. + + + Пример синтаксиса, использующего пространство имен + + + ]]> + + + + + Названия пространств имен PHP и php, и составные названия, + начинающиеся с этих (такие как PHP\Classes), являются зарезервированными для + нужд языка и их не следует использовать в пользовательском коде. + + + + + + Определение пространств имен + + + Хотя любой исправный PHP-код может находиться внутри пространства имен, только + классы, интерфейсы, функции и константы зависят от него. + + + Пространства имен объявляются с помощью зарезервированного слова namespace. + Файл, содержащий пространство имен, должен содержать его объявление в начале + перед любым другим кодом, кроме зарезервированного слова + . + + Объявление единого пространства имен + + +]]> + + + Только выражение declare может находиться перед объявлением + пространства имен для указания кодировки файла. Кроме того, объявлению пространства имен + не должен предшествовать не PHP-код, в том числе лишние пробелы: + + Объявление простого пространства имен + + + +]]> + + + + + Кроме того, в отличии от любой другой конструкции PHP, одно и тоже пространство имен + можно определять в нескольких файлах, что позволяет распределять находящееся в них по файловой системе. + + + + Определение подпространств имен + + + Так же как файлы и каталоги, пространства имен PHP позволяют создавать + иерархию имен. Таким образом, имя пространства может быть определено + с подуровнями: + + Определение пространства имен с иерархией + + +]]> + + + Вышеприведенный пример создает константу MyProject\Sub\Level\CONNECT_OK, + класс MyProject\Sub\Level\Connection и функцию + MyProject\Sub\Level\connect. + + + + Описание нескольких пространств имен в одном файле + + + Несколько пространств имен также можно описать в одном файле с помощью двух допустимых + синтаксических конструкций. + + + + Описание нескольких пространств имен, простой синтаксис + + +]]> + + + + + Данный синтаксис не рекомендуется для комбинирования пространств имен в одном файле. + Вместо этого рекомендуется использовать альтернативный синтаксис со скобками. + + + + Описание нескольких пространств имен, синтаксис со скобками + + +]]> + + + + + Настоятельно не рекомендуется при программировании комбинировать несколько пространств имен + в один файл. Основным применением этому может быть объединение нескольких PHP файлов в + один файл. + + + Для объединения кода в глобальном пространстве имен с кодом в других пространствах имен, + используется только синтаксис со скобками. Глобальный код должен быть + помещен в конструкцию описания пространства имен без указания имени: + + Описание глобального и обычного пространства имен в одном файле + + +]]> + + + + + PHP-код не может находиться вне скобок конструкции пространства имен, кроме + начального выражения declare. + + Описание глобального и обычного пространства имен в одном файле + + +]]> + + + + + + Использование пространства имен: основы + + + До обсуждения использования пространств имен важно понять как PHP узнает + какие элементы из пространства имен запрашиваются в вашем коде. Можно провести аналогию + между пространствами имен PHP и файловой системой. Есть три способа обратиться к файлу + в файловой системе: + + + + Относительное имя файла, такое как foo.txt, преобразуемое в + currentdirectory/foo.txt, где currentdirectory текущая + директория, в которой мы находимся. Тогда, если текущая директория + /home/foo, то имя преобразуется в /home/foo/foo.txt. + + + + + Относительное имя пути, такое как subdirectory/foo.txt, преобразуется + в currentdirectory/subdirectory/foo.txt. + + + + + Абсолютное имя пути, такое как /main/foo.txt, которое остается + таким же: /main/foo.txt. + + + + Тот же принцип применим и к элементам из пространств имен PHP. Для примера, + имя класса может быть указано тремя способами: + + + + Неполные имена (имена классов без префикса), такие как + $a = new foo(); или + foo::staticmethod();. Если текущее пространство имен + currentnamespace, то эти имена преобразуются в + currentnamespace\foo. Если код находится в глобальном + пространстве имен, то имена остаются такими же: foo. + + + Предупреждение: неполные имена для функций и констант будут определяться + в глобальном пространстве имен, если они не определены в текущем пространстве имен. + Подробнее в Использование пространств имен: + доступ к глобальным функциям и классам. + + + + + Полные имена (имена классов с префиксами), такие как + $a = new subnamespace\foo(); или + subnamespace\foo::staticmethod();. Если текущее пространство имен + currentnamespace, то эти имена преобразуются в + currentnamespace\subnamespace\foo. Если + код находится в глобальном пространстве имен, то имена преобразуются в subnamespace\foo. + + + + + Абсолютные имена или имена с предшествующим префиксом, обозначающим глобальное пространство. + $a = new \currentnamespace\foo(); или + \currentnamespace\foo::staticmethod();. Имена всегда + определяются также как и записаны: currentnamespace\foo. + + + + + + Ниже приведен пример трех вариантов синтаксиса в реальном коде: + + file1.php + + + ]]> + + file2.php + + + ]]> + + + + + Обратите внимание, что для доступа к любым глобальным + классам, функциям или константам, может использоваться абсолютное имя, такое как + \strlen, или \Exception, или + \INI_ALL. + + Доступ к глобальным классам, функциям и константам из пространства имен + + + ]]> + + + + + + Пространства имен и динамические особенности языка + + + На реализацию пространств имен в PHP повлияли и динамические особенности языка. + Преобразуем нижеследующий код для использования пространств имен: + + Динамически доступные элементы + example1.php: + + + ]]> + + + Необходимо использовать абсолютное имя (имя класса с префиксом пространства имен). + Обратите внимание, что нет никакой разницы между полным именем и абсолютным + внутри динамического имени класса, функции или константы. Начальный обратный + слэш не является необходимым. + + Динамически доступные элементы пространства имен + + + ]]> + + + + + Обязательно прочитайте примечание об + экранировании имен пространства имен в строках. + + + + Ключевое слово namespace и константа __NAMESPACE__ + + + PHP поддерживает два способа к абстрактно доступным элементамв текущем пространстве имен + таким, как магическая константа __NAMESPACE__ и + ключевое слово namespace. + + + Значение константы __NAMESPACE__ - это строка, которая содержит + имя текущего пространства имен. В глобальном пространстве, вне пространства имен, она + содержит пустую строку. + + Пример использование константы __NAMESPACE__ в коде с пространством имен + + +]]> + + + + Пример использование константы __NAMESPACE__ в глобальном пространстве + + +]]> + + + Константа __NAMESPACE__ полезна для динамически конструируемых + имен, например: + + использование константы __NAMESPACE__ для динамического конструирования имени + + +]]> + + + + + Ключевое слово namespace может быть использовано для + явного запроса элемента из текущего пространства имен или из подпространства. + Это эквивалент оператора self для классов в пространстве имен. + + Оператор namespace, внутри пространства имен + + +]]> + + + + Оператор namespace в глобальном коде + + +]]> + + + + + + Использование пространств имен: импорт/создание псевдонима имени + + + Возможность ссылаться на внешнее абсолютное имя по псевдониму или импортирование + - это важная особенность пространств имен. Это похоже на возможность + файловых систем unix создавать символические ссылки на файл или директорию. + + + Пространства имен PHP поддерживают + три вида создания псевдонима имени или импорта: создание псевдонима для имени класса, создание псевдонима + для имени интерфейса и для имени пространства имен. + Обратите внимание, что импорт функций или констант не поддерживается. + + + В PHP создание псевдонима имени выполняется с помощью оператора use. Вот + пример, показывающий 3 типа импорта: + + импорт/создание псевдонима имени с помощью оператора use + + +]]> + + + Обратите внимание, что для имен в пространстве имен (абсолютные имена, содержащие + разделитель пространств имен, такие как Foo\Bar, в отличие от глобальных имен, + которые его не содержат, такие как FooBar) нет необходимости в начальном обратном слеше (\) + и его присутствие там не рекомендуется, так как импортируемые имена должны быть абсолютными и не обрабатываются + относительно текущего пространства имен. + + + PHP дополнительно поддерживает удобное сокращение для задания нескольких операторов use + в одной и той же строке + + импорт/создание псевдонима имени с помощью оператора use, комбинирование нескольких операторов use + + +]]> + + + + + Импорт выполняется во время компиляции, и не влияет на имена динамических классов, функций + или констант. + + Импорт и динамические имена + + +]]> + + + + + В дополнение, импорт распространяется только на неполные и полные имена. Абсолютные имена + не затрагиваются операцией импорта. + + Импортирование и абсолютные имена + + +]]> + + + + + Scoping rules for importing + + Ключевое слово use должно быть указано в + самом начале файла (в глобальной области) или внутри объявления пространства + имен. Это необходимо потому, что импорт выполняется во время компиляции, а + не во время исполнения, поэтому оно не может быть заключено в блок. + Следующий пример показывает недопустимое применение + ключевого слова use: + + + + Недопустимое правило импорта + + +]]> + + + + + + Правила импорта задаются на каждый файл отдельно. Это означает, что + присоединяемые файлы НЕ будут наследовать правила импорта + из родительского файла. + + + + + + Глобальное пространство + + + Без определения пространства имен, определения всех классов и функций + находятся в глобальном пространстве - также как это было в PHP до введения + пространств имен. Добавление префикса \ к именам означает, что + это имя должно находиться в глобальном пространстве, даже если вы находитесь в + контексте определенного пространства имен. + + Использованиие глобального пространства и его задание + + + ]]> + + + + + + Использование пространств имен: переход к глобальной функции/константе + + + Внутри пространства имен, когда PHP встречает неполное имя класса, функции или + константы, он преобразует эти имена с разными приоритетами. Имена классов всегда + преобразуются к текущему имени пространства имен. Таким образом, чтобы получить доступ + ко внутреннему классу или пользовательскомуклассу вне пространства имен, необходимо + ссылаться по их абсолютному имени. Например: + + Доступ к глобальным классам внутри пространства имен + + + ]]> + + + + + Для функций и констант, PHP будет прибегать к глобальным функциям или константам, + если функция или константа не существует в пространстве имен. + + Необходимость прибегнуть к глобальным функциям/константам внутри пространства имен + + + ]]> + + + + + + + Правила разрешения имен + + + Для этих правил здесь приведены несколько важных определений: + + Определения имени пространства имен + + Неполное имя + + + Это идентификатор без разделителя пространств имен, например, Foo + + + + + Полное имя + + + Это идентификатор с разделителем пространств имен, например, Foo\Bar + + + + + Абсолютное имя + + + Это идентификатор с разделителем пространств имен, который начинается с разделителя пространств имен, + например, \Foo\Bar. Идентификатор namespace\Foo + также является абсолютным именем. + + + + + + + Имена разрешаются согласно следующим правилам: + + + + Вызовы абсолютных функций, классов или констант разрешаются во время компиляции. + Например, new \A\B разрешается в класс A\B. + + + + + Все неполные и полные имена (не абсолютные) переводятся в процессе + компиляции в соответствии с текущими правилами импорта. + Например, если пространство имен A\B\C заимпортировано как + C, вызов + C\D\e() преобразуется к A\B\C\D\e(). + + + + + Внутри пространства имен все полные имена, не переведенные в соответствии + с правилами импорта, получают префикс текущего пространства имен. + Например, если происходит вызов + C\D\e(), он преобразуется внутри пространства имен A\B + к A\B\C\D\e(). + + + + + Неполные имена классов преобразуются в процессе компиляции в соответствии с текущими + правилами импорта (полное имя заменено на короткое импортируемое имя). Например, + если пространство имен A\B\C заимпортировано как C, выражение new C() + преобразовывается к выражению new A\B\C(). + + + + + Внутри пространства имен (скажем, A\B), вызовы к неполным именам функций преобразуются + во время исполнения. Вот, к примеру, как преобразуется вызов + функции foo(): + + + + + Производится поиск функции из текущего пространства имен: + A\B\foo(). + + + + + PHP пытается найти и вызвать функцию глобального пространства + foo(). + + + + + + + Внутри пространства имен (скажем, A\B), вызовы к неполным или полным + именам классов (неабсолютным) + преобразуются во время исполнения. Вот как выражение + new C() или new D\E() преобразуется. + Для new C(): + + + + + Ищется класс из текущего пространства имен: + A\B\C. + + + + + Производится попытка автозагрузки A\B\C. + + + + + Для new D\E(): + + + + + Ищется класс с помощью префиксации текущего пространства имен: + A\B\D\E. + + + + + Производится попытка автозагрузки A\B\D\E. + + + + + Для обращения к любому глобальному классу в глобальном пространстве, + должно использоваться его абсолютное имя new \C(). + + + + + + Примеры разрешения имен + + +]]> + + + + + Часто задаваемые вопросы (FAQ): вещи, которые вам необходимо знать о пространствах имен + + + Этот список вопросов разделен на две части: общие вопросы и некоторые особенности + реализации, которые полезны для более полного понимания. + + + Сперва, общие вопросы. + + + + Если я не использую пространства имен, следует + ли считать что-либо из этого важным ? + + + + + Как мне использовать внутренние или глобальные + классы в пространстве имен ? + + + + + Как мне использовать функции классов в + пространствах имен, или константы в их собственном пространстве имен ? + + + + + + Как такое имя как \my\name или \name + преобразуется ? + + + + + + Как такое имя, как + my\name преобразуется ? + + + + + Как неполное имя класса + такое как name преобразуется ? + + + + + Как неполное имя функции + или неполное имя константы такое + как name преобразуется ? + + + + + + Некоторые детали реализации пространств имен, которые + полезно понимать. + + + + Импортируемые имена не могут конфликтовать с + классами, определенными в том же файле. + + + + + Вложенные пространства имен недопустимы. + + + + + + Ни функции, ни + константы не могут быть заимпортированы с помощью оператора use. + + + + + + Динамические имена пространств имен (идентификаторы, + взятые в кавычки) должны экранировать символ обратного слеша. + + + + + Ссылаться на неопределенные константы, + используя обратный слеш, нельзя. Выводится фатальная ошибка + + + + + Невозможно переопределить специальные + константы, такие как NULL, TRUE, FALSE, ZEND_THREAD_SAFE или ZEND_DEBUG_BUILD + + + + + + Если я не использую пространства имен, следует ли считать что-либо из этого важным ? + + Нет. Пространства имен не оказывают никакого влияния ни на какой существующий код ни в каком виде или + на любой написанный код, который не содержит пространств имен. Вы можете + написать такой код, если желаете: + + + + Доступ к глобальным классам вне пространства имен + + +]]> + + + + + Это функционально эквивалентно следующему: + + + + Доступ к глобальным классам вне пространства имен + + +]]> + + + + + + Как мне использовать внутренние или глобальные классы в пространстве имен ? + + + Доступ ко внутренним классам в пространствах имен + + +]]> + + + + + + + Как мне использовать функции классов в пространствах имен, или + константы в их собственном пространстве имен ? + + + + Доступ ко внутренним классам, функциям или константам в пространствах имен + + +]]> + + + + + + + Как такое имя как <literal>\my\name</literal> или <literal>\name</literal> + преобразуется ? + + + Имена, которые начинаются с \ всегда преобразуются к тому как + они выглядят, т.е. \my\name - это на самом деле my\name, + и \Exception - это Exception. + + Абсолютные имена + + +]]> + + + + + + Как такое имя, как <literal>my\name</literal> преобразуется ? + + Имена, которые содержат обратный слеш, но не начинаются с него, такие как + my\name могут быть преобразованы двумя различными способами. + + + Если присутствует + импортирующее выражение, которое создает синоним my другого имени, то + этот синоним применяется к my в my\name. + + + В ином случае, текущее имя пространства имен становится префиксом к my\name. + + + + Полные имена + + +]]> + + + + + + Как неполное имя класса такое как <literal>name</literal> преобразуется ? + + Имена классов, которые не содержат обратный слеш, такие как + name могут быть преобразованы двумя различными способами. + + + Если присутствует + импортирующее выражение, которое создает синоним name другого имени, то + применяется этот синоним. + + + В ином случае, текущее имя пространства имен становится префиксом к my\name. + + + + Неполные имена классов + + +]]> + + + + + + Как неполное имя функции или неполное имя константы такое + как <literal>name</literal> преобразуется ? + + + Имена функций или констант, которые не содержат обратного слеша, такие как + name могут быть преобразованы двумя различными способами. + + + Сперва, текущее имя пространства имен становится префиксом к name. + + + Затем, если константа или функция name не существует + в текущем пространстве имен, используется глобальная константа или функция name, + если она существует. + + + + Неполные имена функций или констант + + +]]> + + + + + + Импортируемые имена не могут конфликтовать с классами, определенными в том же файле. + + Следующие комбинации скриптов допустимы: + + file1.php + + + ]]> + + another.php + + + ]]> + + file2.php + + + ]]> + + + + + Конфликт имен отсутствует даже несмотря на то, что класс MyClass существует + внутри пространства имен my\stuff, потому что определение MyClass + находится в отдельном файле. Однако следующий пример приводит к фатальной ошибке с конфликтом + имен, потому что класс MyClass определен в том же файле, где находится оператор use. + + + + ]]> + + + + + + Вложенные пространства имен недопустимы. + + PHP не позволяет вложение пространств имен одно в другое + + + + ]]> + + + Однако, сымитировать вложенные пространства имен так: + + + + ]]> + + + + + + Ни функции, ни константы не могут быть заимпортированы с помощью оператора <literal>use</literal>. + + Элементы, которые подвержены действию оператора use - это пространства имен и + имена классов. Для сокращения длинных имен констант или функций, заимпортируйте их содержимое + в пространство имен. + + + + ]]> + + + + + + Динамические имена пространств имен (идентификаторы, взятые в кавычки) должны экранировать символ обратного слеша. + + Очень важно представлять это, потому что обратный слеш используется как экранирующий символ + внутри строк. Он всегда должен быть продублирован, когда используется внутри строки, иначе + появляется риск возникновения неумышленных последствий: + + Подводные камни при использовании имени пространства имен внутри строки с двойными кавычками + + + ]]> + + + Внутри строк, заключенных в одинарные кавычки, обратный слеш в качестве разделителя более безопасен, но + по-прежнему рекомендуемая практика экранирования обратного слеша во всех строках является наилучшим вариантом. + + + + Ссылаться на неопределенные константы, используя обратный слеш, нельзя. Выводится фатальная ошибка + + Любая неопределенная константа, являющаяся неполным именем, как FOO, будет + приводить к выводу сообщения о том, что PHP предположил, что FOO было значение + константы. Любая константа, с полным именеи или абсолютным, которая содержит + символ обратного слеша будет приводить к фатальной ошибке, если не будет найдена. + + Неопределенные константы + + + ]]> + + + + + + Невозможно переопределить специальные константы, такие как NULL, TRUE, FALSE, ZEND_THREAD_SAFE или ZEND_DEBUG_BUILD + + Любая попытка определить константу пространства имен, которая совпадает с названиями специальных встроенных констант, + приведет к фатальной ошибке. + + Неопределенные константы + + + ]]> + + + + + + + +