Как реализовать автозагрузчик с пространствами имен в вашей теме или плагине WordPress
Если вы пишете объектно-ориентированный код, автозагрузчик просто необходим. Без автозагрузчика вам нужно было бы добавить строку с включением файла класса, прежде чем вы сможете его инициализировать. Это может быстро стать громоздким, когда вы работаете с большим количеством классов. Автозагрузчик — это функция, которая срабатывает каждый раз, когда создается экземпляр нового класса, и включает файл класса до того, как произойдет создание экземпляра.
Пространства имен — это способ структурирования и инкапсуляции кода, помогающий избежать конфликтов имен. Если вы собираетесь писать ООП, рекомендуется также использовать пространства имен. Имейте в виду, что вы можете реализовать автозагрузчик без использования пространств имен в вашем коде ООП.
Вы можете использовать этот код для своей темы или плагина WordPress или любого PHP-кода вне WordPress, если на то пошло — просто измените пути соответствующим образом. В этом примере я создаю автозагрузчик для темы WordPress.
Правила для пространства имен и структуры класса
Реализация автозагрузчика потребует некоторых определенных правил для вашей структуры кода и того, где их найти. Использование пространств имен несколько упрощает это, поскольку ваше пространство имен может ссылаться на папку, в которой находятся классы.
Сначала примите решение о том, как назвать ваше пространство имен. Обычно это что-то уникальное для вашего кода, например, название вашей темы. Например, пространство имен для темы этого сайта — AWhitePixelTheme
. Это означает, что для работы автозагрузчика любые классы должны находиться внутри этого пространства имен.
namespace AWhitePixelTheme;
Мое первое правило заключается в том, что любой файл класса всегда будет содержать только один класс, и имя класса должно совпадать с именем файла. Например; класс MyTest
должен быть определен внутри файла MyTest.php
.
Мое второе правило заключается в том, как структурировать классы по папкам. Я решаю, что все классы помещаются в папку src
в моей теме. Я могу поместить файлы классов прямо в эту папку, и для этого они должны находиться внутри «корневого» пространства имен, определенного выше. Но если я хочу создать подпапки и поместить в них файлы классов, их пространства имен должны включать структуру папок. Например, класс файл MyTest.php
, который находится в папке src/Test/
, должен иметь это пространство имен:
namespace AWhitePixelThemeTest;
Создание автозагрузчика
Мне нравится хранить автозагрузчик в отдельном файле и вне src/
папки, которая определена только для файлов классов с пространством имен. В качестве примера я создам файл autoloader.php
в папке inc/
моей темы.
PHP имеет встроенную функцию автозагрузчика: spl_autoload_register. Вы указываете имя функции автозагрузчика в качестве параметра, и в этой функции вы получаете запрошенный класс в качестве аргумента (то, что вы ставите после new
создания экземпляра класса). При создании экземпляров классов с пространствами имен, например new AWhitePixelThemeTestMyTest()
, предоставленной переменной для этой функции будет "AWhitePixelThemeTestMyTest"
.
Добавим функцию автозагрузчика, и в ней определим наше необходимое пространство имен для автозагрузчика:
Затем нам нужно подключить этот файл, чтобы наш автозагрузчик был зарегистрирован. Поскольку это в теме, я добавлю включение в файл темы functions.php
. Если вы используете это для плагина, поместите его в свои файлы плагина. Файл автозагрузчика необходимо добавить заранее, до создания экземпляров классов. Я помещаю это в самую первую строку в моем functions.php
:
require_once(get_template_directory(). '/inc/autoloader.php');
Если вы используете его для дочерней темы или плагина, измените путь в соответствии с вашими потребностями.
Вот и все. Теперь автозагрузчик на месте, но ничего не делает. Вернемся к функции автозагрузчика и закончим с ней.
Написание и тестирование функции автозагрузчика
Сначала нам нужно убедиться, что запрошенное имя класса действительно находится внутри нашего пространства имен. Мы просто проверяем, содержит ли предоставленное имя класса пространства имен строку пространства имен, и если нет, выходим из функции. После этого мы удаляем имя пространства имен из строки, чтобы мы могли работать с любыми подпапками и файлом класса.
Теперь мы преобразуем предоставленное пространство имен в фактический путь к файлу. Во- первых, мы заменим любую обратную косую черту ""
в пространстве имен символом разделителя папок — для этого мы используем константу PHP DIRECTORY_SEPARATOR
. В самом конце добавляем ".php"
. И, наконец, перед строкой мы добавляем полный корневой путь. Поскольку это внутри темы, я использую get_template_directory()
. Если вы используете это для плагина, используйте метод, который возвращает полный путь к вашему плагину.
...
$class = str_replace($namespace, '', $class);
$class = str_replace('', DIRECTORY_SEPARATOR, $class). '.php';
$directory = get_template_directory();
$path = $directory. DIRECTORY_SEPARATOR. 'src'. DIRECTORY_SEPARATOR. $class;
}
Все, что нам нужно сделать сейчас, это проверить, существует ли файл, и, если он существует, потребовать его.
...
$path = $directory. DIRECTORY_SEPARATOR. 'src'. DIRECTORY_SEPARATOR. $class;
if (file_exists($path)) {
require_once($path);
}
}
Вот и все!
Давайте проверим это. Создайте подпапку Test
в src/
папке вашей темы и поместите в нее php-файл с именем MyTest.php
. Определите в нем класс MyTest
, следуя правилам пространства имен: AWhitePixelThemeTest
. Я просто добавлю печать «Успех» в функцию конструкции, чтобы мы могли легко увидеть, что она фактически инициализирует класс.
В нашем functions.php после запроса автозагрузчика мы просто создаем экземпляр класса:
$test = new AWhitePixelThemeTestMyTest();
Обновите свой сайт WordPress и убедитесь, что вы получили сообщение «Успех!» выведено.
Автозагрузчик будет автоматически загружать любые файлы классов, которые находятся внутри нашего определенного пространства имен, и следует правильным правилам. Вы можете создавать экземпляры классов из любой точки вашей темы, даже внутри самих классов.
Полная функция автозагрузчика
Для справки, вот наша последняя функция автозагрузчика:
spl_autoload_register('awhitepixel_autoloader');
function awhitepixel_autoloader($class) {
$namespace = 'AWhitePixelTheme';
if (strpos($class, $namespace) !== 0) {
return;
}
$class = str_replace($namespace, '', $class);
$class = str_replace('', DIRECTORY_SEPARATOR, $class). '.php';
$directory = get_template_directory();
$path = $directory. DIRECTORY_SEPARATOR. 'src'. DIRECTORY_SEPARATOR. $class;
if (file_exists($path)) {
require_once($path);
}
}