Класс Автозагрузчик
Phalcon\Loader позволяет автоматически загружать классы проекта, основываясь на некоторых предопределённых правилах. Поскольку этот компонент написан на C, он обеспечивает минимальную нагрузку при чтении и интерпретации внешних файлов PHP.
Поведение этого компонента основано на возможности PHP автоматической загрузки классов. Если класс, которого ещё нет, используется в какой-либо части кода, специальный обработчик попытается загрузить его. Phalcon\Loader служит специальным обработчиком для этой операции. Загрузка классов по мере необходимости увеличивает общую производительность, поскольку чтение файлов происходит только для необходимых файлов. Эта техника называется ленивой инициализацией.
С помощью этого компонента вы можете загружать файлы из других проектов или поставщиков; этот автозагрузчик совместим со спецификациями PSR-0 и PSR-4.
Phalcon\Loader предлагает четыре варианта для автоматической загрузки классов. Вы можете использовать их по одному или комбинировать.
Уровень безопасности
Phalcon\Loader по умолчанию предлагает уровень безопасности, очищающий имена классов, предотвращая возможное включение несанкционированных файлов. Рассмотрим следующий пример:
// Basic autoloader
spl_autoload_register(
function ($className) {
$filepath = $className . ".php";
if (file_exists($filepath)) {
require $filepath;
}
}
);
Указанный выше автозагрузчик не имеет никакого вида защиты. Если функция ошибочно запускает автозагрузчик, и в качестве параметра используется вредоночная подготовленная строка, это позволит выполнить любой файл, доступный для приложения:
// This variable is not filtered and comes from an insecure source
$className = "../processes/important-process";
// Check if the class exists triggering the auto-loader
if (class_exists($className)) {
// ...
}
Если ‘../processes/important-process.php’ — это действительный файл, внешний пользователь мог бы выполнить этот файл без авторизации.
Чтобы избежать этих или более сложных атак, Phalcon\Loader удаляет недопустимые символы из имени класса, уменьшая возможность атаки.
Регистрация пространств имён
Если вы организуете свой код с использованием пространств имён или используете внешние библиотеки, которые это делают, метод registerNamespaces() обеспечивает механизм автоматической загрузки. Он принимает ассоциативный массив; ключи — это префиксы пространств имён, а значения — это каталоги, где расположены классы. Разделитель пространств имён заменяется разделителем каталогов, когда загрузчик пытается найти классы. Всегда помните, что в конце путей должен стоять косой слэш.
use Phalcon\Loader;
// Creates the autoloader
$loader = new Loader();
// Register some namespaces
$loader->registerNamespaces(
[
"Example\Base" => "vendor/example/base/",
"Example\Adapter" => "vendor/example/adapter/",
"Example" => "vendor/example/",
]
);
// Register autoloader
$loader->register();
// The required class will automatically include the
// file vendor/example/adapter/Some.php
$some = new \Example\Adapter\Some();
Регистрация каталогов
Третий вариант — зарегистрировать каталоги, в которых могут находиться классы. Этот вариант не рекомендуется с точки зрения производительности, так как Phalcon должен будет выполнить значительное количество операций с файлами для каждого каталога, ища файл с тем же именем, что и класс. Важно регистрировать каталоги в порядке важности. Всегда помните, что в конце путей должен стоять косой слэш.
use Phalcon\Loader;
// Creates the autoloader
$loader = new Loader();
// Register some directories
$loader->registerDirs(
[
"library/MyComponent/",
"library/OtherComponent/Other/",
"vendor/example/adapters/",
"vendor/example/",
]
);
// Register autoloader
$loader->register();
// The required class will automatically include the file from
// the first directory where it has been located
// i.e. library/OtherComponent/Other/Some.php
$some = new \Some();
Регистрация классов
Последний вариант — зарегистрировать имя класса и его путь. Этот автозагрузчик может быть очень полезным, когда соглашение об именовании файлов проекта не позволяет легко получить файл, используя путь и имя класса. Это самый быстрый метод автоматической загрузки. Однако по мере роста приложения потребуется добавлять больше классов/файлов в этот автозагрузчик, что существенно затруднит обслуживание списка классов, поэтому это не рекомендуется.
use Phalcon\Loader;
// Creates the autoloader
$loader = new Loader();
// Register some classes
$loader->registerClasses(
[
"Some" => "library/OtherComponent/Other/Some.php",
"Example\Base" => "vendor/example/adapters/Example/BaseClass.php",
]
);
// Register autoloader
$loader->register();
// Requiring a class will automatically include the file it references
// in the associative array
// i.e. library/OtherComponent/Other/Some.php
$some = new \Some();
Регистрация файлов
Вы также можете зарегистрировать файлы, которые являются «не классами», поэтому требуют «require». Это очень полезно для включения файлов, содержащих только функции:
use Phalcon\Loader;
// Creates the autoloader
$loader = new Loader();
// Register some classes
$loader->registerFiles(
[
"functions.php",
"arrayFunctions.php",
]
);
// Register autoloader
$loader->register();
Эти файлы автоматически загружаются в методе register().
Дополнительные расширения файлов
Некоторые стратегии автоматической загрузки, такие как «префиксы», «пространства имён» или «каталоги», автоматически добавляют расширение «php» в конце проверяемого файла. Если вы используете дополнительные расширения, вы можете установить их с помощью метода «setExtensions». Файлы проверяются в том порядке, в котором они были определены:
use Phalcon\Loader;
// Creates the autoloader
$loader = new Loader();
// Set file extensions to check
$loader->setExtensions(
[
"php",
"inc",
"phb",
]
);
Изменение текущих стратегий
Дополнительные данные для автоматической загрузки могут быть добавлены к существующим значениям, передав «true» в качестве второго параметра:
// Adding more directories
$loader->registerDirs(
[
"../app/library/",
"../app/plugins/",
],
true
);
События автоматической загрузки
В следующем примере EventsManager работает с загрузчиком классов, позволяя получить информацию об отладке о ходе операции:
use Phalcon\Events\Event;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Loader;
$eventsManager = new EventsManager();
$loader = new Loader();
$loader->registerNamespaces(
[
"Example\\Base" => "vendor/example/base/",
"Example\\Adapter" => "vendor/example/adapter/",
"Example" => "vendor/example/",
]
);
// Listen all the loader events
$eventsManager->attach(
"loader:beforeCheckPath",
function (Event $event, Loader $loader) {
echo $loader->getCheckedPath();
}
);
$loader->setEventsManager($eventsManager);
$loader->register();
Некоторые события при возвращении значения false могут остановить активную операцию. Поддерживаются следующие события:
| Имя события | Вызвано | Остановить операцию? | |
|---|---|---|---|
| beforeCheckClass | Вызывается перед началом процесса автоматической загрузки | Да | |
| pathFound | Вызывается, когда загрузчик находит класс | Нет | |
| afterCheckClass | Вызывается после завершения процесса автоматической загрузки. Если это событие запущено, автозагрузчик не нашёл файл класса | Нет | |
Устранение неполадок
Некоторые моменты, которые следует учитывать при использовании универсального автозагрузчика:
- Процесс автоматической загрузки чувствителен к регистру; класс загружается так, как он написан в коде
- Стратегии, основанные на пространствах имён/префиксах, быстрее, чем стратегия каталогов
- Если установлен кэш байткода, например, APC, он будет использоваться для получения запрошенного файла (выполняется неявное кеширование файла)
© 2011–2017 Phalcon Framework Team
Licensed under the Creative Commons Attribution License 3.0.
https://docs.phalconphp.com/en/latest/reference/loader.html