Сайт FSA
16.07.2022

Самый быстрый и простой способ автозагрузки классов в PHP

Сейчас большинство серьёзных разработчиков на PHP использует composer, который предоставляет возможность включить автозагрузку классов просто подключив файл. Однако для очень простых проектов использование composer может оказаться избыточным. Если весь ваш проект не использует внешних зависимостей и весь код написан вами, то и смысла использовать composer нет.

Используем автозагрузку в своём минипроекте

Обычно в документации описан вариант с созданием своей функции для автозагрузки классов с использованием spl_autoload_register(). Она позволяет зарегистрировать функцию, которая будет заниматься автозагрузкой классов. Функций может быть зарегистрировано несколько и ни окажутся в SPL очереди. spl_autoload_register() принимает в качестве первого параметра callback метод, который будет вызываться в тех случаях, когда будет требоваться обращение к классу, который ещё не был объявлен ранее в коде. Однако, данная функция, кроме callback, может принимать и значение null, что является значением по умолчанию. В этом случае поиск путей к необходимым классам будут производиться по путям, которые указаны в параметре конфигурации include_path. Значение этого параметра можно изменить с помощью функции set_include_path().

Чтобы установить расширения для файлов, в которых будут храниться классы, можно использовать функцию spl_autoload_extensions(). В PHP 8.1 значение по умолчанию .inc,.php. По моему мнению, использование расширения .inc небезопасно, поскольку некоторые хостинги могут выдавать содержимое файлов .inc в виде текста, поскольку веб-сервер должен быть соответствующим образом настроен для передачи этих файлов PHP или запрета их просмотра.

Таким образом, чтобы добавить автозагрузку классов нам необходим следующий код:

set_include_path(get_include_path().':'.__DIR__.'/classes/');
spl_autoload_extensions('.php');
spl_autoload_register();

Этот код можно ещё более сократить, поскольку вряд ли вы будете использовать include_path в своём небольшом проекте. Можно отбросить текущее значение и указать только своё.

set_include_path(__DIR__.'/classes/');
spl_autoload_extensions('.php');
spl_autoload_register();

Путь можно ещё больше сократить исключив константу __DIR__, которая указывает на каталог расположения файла, где хранится этот код, но тогда путь до папки с классами будет зависеть от текущей директории во время исполнения кода. Используйте следующий вариант, если действительно знаете что делаете:

set_include_path('classes/');
spl_autoload_extensions('.php');
spl_autoload_register();

Согласно PSR-4 для обеспечения автозагрузки имена папок и файлов должны соответствовать пространствам имён (namespace) и именам классов. Однако стандартный автозагрузчик требует, чтобы все имена были переведены в нижний регистр. Т.е. если ваш класс с именем MyClass расположен в пространстве имён MyNS, то для обеспечения его автозагрузки необходимо расположить по пути myns/myclass.php в папке, которую указали в include_path.

<?php
# myns/myclass.php
namespace MyNS;

class MyClass {
...
}

При желании можно указать суффикс для файлов с классами, например так:

set_include_path(__DIR__.'/classes/');
spl_autoload_extensions('.class.php');
spl_autoload_register();

Тогда поиск класса будет производиться в файле myns/myclass.class.php.

Заключение

Приведённый в заметке метод не соответствует современному стандарту автозагрузки классов PSR-4, но он имеется в стандартной поставке PHP. Его можно использовать там, где не требуется установка зависимостей через composer. Он позволит сэкономить немного тактов процессора на сервере, поскольку при автозагрузке код на PHP вообще не используется, но на современном железе и с небольшим количеством подключаемых файлов практически не даёт заметного выигрыша. Однако метод рабочий и его можно использовать в небольших проектах.


Обратите внимание, что заметки могут обновляться со временем. Это может быть как исправление найденных ошибок, так и доработка содержания с целью более полного раскрытия темы. Информация об изменениях доступна в репозитории на github. Там же вы можете оставить в Issue ваши замечания по данной заметке.


Если данная заметка оказалась вам полезной, можете поблагодарить автора финансово.