Пространства имён PHP в WordPress — руководство без излишеств
Опубликовано: 2018-10-16Пространствам имен PHP почти десять лет. Да, десятилетие прошло (и да, вы стареете). Несмотря на десятилетие, прошедшее с момента выпуска PHP v5.3, многие разработчики до сих пор не имеют базового представления о пространствах имен. По правде говоря , WordPress не использует пространства имен , поэтому « вам не нужно знать, как использовать пространства имен, если вы работаете только с WordPress ». Вам не нужно быть ниндзя пространства имен, но понять основы несложно, и это пойдет вам на пользу.
Пространства имен PHP существуют уже десять лет, а вы до сих пор их не используете, потому что #wordpress тоже не использует? Прочитайте и начните использовать их через 2 минуты! #разработка
НАЖМИТЕ, ЧТОБЫ НАПИСАТЬКогда нет поддержки пространства имен — используйте префикс
Долгое-долгое время в PHP не было встроенной поддержки пространств имен. Вот почему WordPress и многие другие крупные кодовые базы не используют нативные пространства имен. Их не было рядом, когда они были нужны, поэтому используются префиксы.
Пространство имен важно, потому что оно гарантирует, что ваша функция write_to_log()
еще не определена другим фрагментом кода. Чтобы избежать конфликта имен, все в глобальной области видимости нуждается в префиксе, поэтому функция становится awesome_project_write_to_log()
а все остальные функции и переменные также получают префикс awesome_project_
. Простой? Это! Симпатичный? Не совсем.
Есть несколько альтернатив этому подходу, например инкапсуляция статических методов. Вы оборачиваете все свои функции в класс и объявляете их как статические методы. Затем вместо вызова my_function()
вы вызываете My_Class::my_function()
. Лучше? Немного, но все же не правильное пространство имен.
Давайте посмотрим, как пространство имен позволяет нескольким фрагментам кода (или пакетам, если хотите) использовать одни и те же имена классов и функций без конфликтов. Или, как сказано в руководстве по PHP, как они включают инкапсуляцию кода. Их аналогия с файлами и папками также уместна — во многих отношениях пространства имен ведут себя точно так же, как папки, поэтому я скопирую/вставлю из руководства;
В любой операционной системе каталоги служат для группировки связанных файлов и действуют как пространство имен для файлов внутри них. Например, файл foo.txt может существовать как в каталоге /home/greg, так и в /home/other, но две копии foo.txt не могут сосуществовать в одном каталоге. Чтобы получить доступ к файлу foo.txt за пределами каталога /home/greg, мы должны добавить полное имя каталога к имени файла, используя разделитель каталогов, чтобы получить /home/greg/foo.txt.
Объявление пространств имен — помните первую строку
Пространство namespace
ключевых слов должно быть первой строкой кода в файле (не считая комментариев и любого содержимого, отличного от PHP). Пространства имен влияют только на классы, интерфейсы, функции и константы. Они не влияют на переменные. Вы можете определить одно и то же пространство имен в нескольких файлах, что позволит разделить код на несколько файлов. Подпространства имён позволяют определять иерархию в пространствах имён так же, как и в папках, используя обратную косую черту — namespace myproject\level1\level2
. Это основные и почти все правила объявления пространств имен.
// file-A.php contains a function under the myCompany\PackageA namespace namespace myCompany\PackageA; function do_something() { // do things }
// file-B.php contains a function with the same name // but under a different namespace namespace myCompany\PackageB; function do_something() { // do things }
Хотя это возможно, я настоятельно рекомендую не объединять несколько пространств имен в один файл. Поверьте мне, рано или поздно вы забудете, что сделали это, а отладка двухминутной ошибки займет два часа. Однако, если вам нужно, вот синтаксис.

// do not put multiple namespace declarations into the same file // but if you must, here's the syntax namespace MyFirstProject { const CONST = true; class Connection { /* ... */ } function connect() { /* ... */ } } namespace MySecondProject { const CONST = true; class Connection { /* ... */ } function connect() { /* ... */ } } // any code after this has to go in the global namespace namespace { $some_var = 1; function_in_global_namespace(); }
Использование пространств имен — запоминайте папки
Как я уже говорил, пространства имен очень похожи на папки. Предполагая, что файл foo.txt
находится в вашей текущей папке; вы можете сослаться на него с помощью простого foo.txt
. Если вы находитесь на один уровень выше папки с файлом foo.txt
, вам нужно использовать относительный путь ../foo.txt
или абсолютный /folder1/folder2/foo.txt
. Ничего особенного. Пространства имен используют ту же парадигму.
// remember after declaring a namespace // all our code is in it; like when you're working in a folder namespace mycompany\project; function foo() {} class foo { static function staticmethod() {} } // resolves to mycompany\project\foo() because of line #3 foo(); // likewise, resolves to mycompany\project\foo::staticmethod() foo::staticmethod(); // constant are affected by namespaces too // so we're working with mycompany\project\FOO echo FOO; // this is a relative path // resolves to mycompany\project\subnamespace\foo() subnamespace\foo(); // static methods are no different // mycompany\project\subnamespace\foo::staticmethod() subnamespace\foo::staticmethod(); // a full namespace path starts with a backslash // it resolves exactly to what it says it does \otherNamespace\Bar\foo(); // again same thing for a constant, full path nothing magical echo \otherNamespace\Bar\FOO;
Взгляните на ключевое слово use
в руководстве по PHP — отличные примеры. Он предоставляет способ импортировать код из других пространств имен PHP в текущее пространство имен или ссылаться на внешнее (полное) имя с псевдонимом.
Да, вам нужны пространства имен, и вы должны их использовать
Как видно из исходного кода WordPress, вам не нужно использовать пространства имен, но вы должны использовать какой-то метод пространства имен. wp_
в случае WP. Итак, если мы уже делаем это, почему бы не сделать это должным образом?
Пространства имен в PHP легко интегрируются в любой рабочий процесс разработки. Они упрощают автозагрузку, именование файлов и в целом делают код чище. Рефакторинг старого кода никогда не был популярной задачей (независимо от языка программирования), поэтому я не собираюсь говорить вам, чтобы вы продолжали рефакторинг работающего 2-мегабайтного проекта только для того, чтобы вы могли сказать, что используете пространства имен. Однако я настаиваю на том, чтобы вы использовали пространства имен при работе над новыми проектами. Вы поблагодарите себя достаточно скоро.
Официальная документация PHP по пространствам имен превосходна! Образцы кода чисты, а комментарии полезны в реальном мире. Обязательно просмотрите его, даже если вы не думаете, что вам это нужно.