DevTips — Пространства имен в PHP
Опубликовано: 2020-03-06Около года назад WordPress решил обновить требуемую минимальную версию PHP с 5.2 (используется с 2010 года) до чего-то более современного. Фактически, на сегодняшний день минимальная версия PHP, рекомендуемая WordPress, является одной из самых последних: PHP 7.3.
Если вы простой пользователь WordPress, это, вероятно, не слишком сильно на вас повлияет (за исключением того факта, что эти новые версии обеспечивают лучшую производительность).
Но если вы разработчик, эти новые версии PHP имеют несколько замечательных функций, которые вы можете использовать в своих плагинах и темах. И сегодня, в частности, я хотел бы поговорить с вами о том, что было с нами долгое время, но: пространства имен.
WordPress и префиксы кода
Одно из первых правил, которое вы усвоите как разработчик WordPress, — «использовать префиксы во всем, что мы делаем», чтобы избежать «конфликтов имен». Как мы можем прочитать в лучших практиках WordPress:
Конфликт имен возникает, когда ваш плагин использует то же имя для переменной, функции или класса, что и другой плагин.
[Во избежание конфликтов имен] все переменные, функции и классы должны иметь префикс с уникальным идентификатором. Префиксы не позволяют другим плагинам перезаписывать ваши переменные и случайно вызывать ваши функции и классы. Это также помешает вам сделать то же самое.
Лучшие практики разработки плагинов WordPress
Таким образом, например, вместо того, чтобы создавать функцию типа get_site_id , лучше назвать ее nelio_content_get_site_id . Таким образом, мы можем быстро определить плагин ( nelio_content ) или тему, к которой принадлежит определенная функция ( get_site_id ), и избежать фатальных ошибок, если несколько плагинов попытаются определить одну и ту же функцию.
Использование префиксов — это рудиментарный способ создания «пространства имен»; обходной путь, который нам пришлось реализовать, когда у нас не было лучшей альтернативы. Все те элементы, которые используют один и тот же префикс, являются частью одного набора или пространства имен. Но это приводит к излишне сложному коду: имена становятся длиннее из-за префиксов, которые не служат никакой другой цели, кроме имитации пространств имен.
Пространства имен PHP
PHP версии 5.3 представил концепцию пространства имен . Определение, которое они дают в документации, кажется мне превосходным, поэтому я воспроизвожу его здесь:
В самом широком смысле пространства имен — это способ инкапсуляции элементов. Во многих местах это можно рассматривать как абстрактное понятие. Например, в любой операционной системе каталоги служат для группировки связанных файлов и действуют как пространство имен для файлов внутри них. В качестве конкретного примера файл foo.txt может существовать как в каталоге /home/greg , так и в /home/other , но две копии foo.txt не могут сосуществовать в одном каталоге.
В мире PHP пространства имен предназначены для решения двух проблем, с которыми сталкиваются авторы библиотек и приложений при создании повторно используемых элементов кода, таких как классы или функции:
1. Назовите коллизии между кодом, который вы создаете, и внутренним кодом PHP или сторонним кодом.
2. Возможность использовать псевдонимы (или сокращать) Extra_Long_Names , улучшая читаемость исходного кода.
PHP-документы
Как создать пространство имен
Создать пространство имен в PHP чрезвычайно просто. В начале создаваемого файла PHP добавьте директиву namespace с именем, которое вы хотите использовать, и «все», что вы определите в этом файле, будет принадлежать этому пространству имен:
<?php namespace Nelio_Content; Да, это так просто! Теперь «все», что мы там создадим, будет находиться в пространстве имен Nelio_Content . Например, если я определяю функцию, подобную той, которую я упоминал в начале:
<?php namespace Nelio_Content; function get_site_id() { // ... } теперь мы знаем, что get_site_id находится внутри пространства имен Nelio_Content . Таким образом, нам больше не нужно использовать префикс nelio_content_ при определении функции. Здорово!
Исключения для пространств имен
Если вы внимательно посмотрите на то, что я сказал вам до сих пор, вы увидите, что я писал «все» в кавычках: «все», что мы туда добавим, будет принадлежать указанному пространству имен». Почему я это сделал? Поскольку пространства имен не применяются абсолютно ко всему коду, который мы пишем… есть некоторые исключения.
Пространства имен PHP охватывают только следующие элементы PHP:

- Классы
- Интерфейсы
- Черты
- Функции
- Константы, объявленные с помощью
constно не с помощьюdefine
Кроме того, в WordPress есть некоторые дополнительные вещи, которые также нуждаются в собственных пространствах имен и, к сожалению, пространства имен PHP не охватывают: ваши скриптовые дескрипторы , параметры базы данных или пользовательские типы контента и их метаданные и т. д. Во всех этих случаях вы должны продолжайте использовать префиксы.
Как импортировать элементы из одного пространства имен в другое
Если вам нужно использовать элемент, который находится в вашем собственном пространстве имен, вам не нужно делать ничего особенного: просто вызовите его по имени. Например, в следующем фрагменте кода:
<?php namespace Nelio_Content; function get_site_id() { // ... } function get_auth_token() { $site_id = get_site_id(); // ... } Как видите, мы определили две функции: get_site_id и get_auth_token , обе в пространстве имен Nelio_Content . Когда get_auth_token нужно использовать get_site_id , он просто вызывает его как обычно.
Если, с другой стороны, вам нужно использовать get_site_id в другом пространстве имен, вы должны вызвать функцию, используя ее полный идентификатор:
<?php namespace Something_Else; function do_some_action() { $site_id = Nelio_Content\get_site_id(); // ... } или вы должны импортировать функцию с use ключевого слова:
<?php namespace Something_Else; use Nelio_Content\get_site_id; function do_some_action() { $site_id = get_site_id(); // ... } Лично мне очень нравится второй вариант: используя ключевое слово use для импорта функций из других пространств имен, вы можете быстро просмотреть заголовок вашего файла и определить его зависимости.
Фильтры и действия WordPress с пространствами имен PHP
Есть важная деталь, о которой следует помнить при использовании пространств имен рядом с фильтрами и действиями WordPress. Когда вы указываете обратные вызовы фильтра и действия, обычно вы делаете это, задавая имя обратного вызова в виде строки:
<?php // ... add_action( 'init', 'do_some_action' );Проблема в том, что если эта функция находится в пространстве имен, предыдущий хук не будет работать должным образом; вы должны сообщить WordPress полное имя функции. Другими словами, вы должны включить его пространство имен (если оно есть).
Вы добавляете хук в файл, где вы определяете само пространство имен? Неважно, используйте полное имя:
<?php namespace Nelio_Content; function do_some_action() { // ... } add_action( 'init', 'Nelio_Content\do_some_action' ); Вы находитесь в другом пространстве имен, но импортировали функцию с use ? Это тоже не имеет значения, используйте полное имя:
<?php namespace Something_Else; use Nelio_Content\do_some_action; // ... add_action( 'init', 'Nelio_Content\do_some_action' );Использование псевдонимов с нашими пространствами имен
Еще одна очень интересная функциональность пространств имен — псевдонимы. Представьте себе следующий сценарий:
<?php namespace Nelio_Content; function get_site_id() { // ... } Если я хочу использовать эту функцию в другом пространстве имен, мы уже видели, что я могу сделать это с use . Но как мне использовать эту функцию, если модуль, в котором я хочу ее использовать, уже имеет функцию с именем get_site_id ?
Что ж, к счастью для меня, мы можем связать наш импорт с новыми именами:
<?php namespace Something_Else; use Nelio_Content\get_site_id as get_nc_site_id(); function get_site_id() { // ... } function do_some_action() { $nc_site_idd = get_nc_site_id(); // ... }Начните использовать пространства имен сегодня!
Пространства имен — фантастический инструмент для предотвращения конфликтов имен и организации нашего кода. На самом деле, и хотя я не комментировал этот пост, существуют стандарты, такие как PSR-4, которые позволяют PHP автоматически загружать классы на основе структуры используемых вами пространств имен и того, как вы организуете код в каталоги и файлы.
Если вы еще не используете пространства имен в своих проектах, мы рекомендуем начать делать это прямо сейчас. Расскажите нам о своем опыте в комментариях!
Избранное изображение Chaitanya Tvs на Unsplash.
