Preloading
Начиная с PHP 7.4.0 можно настроить предзагрузку скриптов в opcache в момент старта PHP.
Любые функции, классы, интерфейсы или трейты (но не константы) в этих файлах будут глобально доступны для всех запросов без необходимости
их явной загрузки. Такая предзагрузка позволяет добиться большего удобства и производительности (потому что код
всегда доступен) за счёт использования большего количества памяти. Также, при внесении изменений в предзагруженные
скрипты, чтобы эти изменения стали доступны, придётся перезагрузить PHP. Из этого следует, что предзагрузку имеет смысл
использовать только в производственном окружении, но не в окружении разработки.
Обратите внимание, что баланс повышения производительности и потребления памяти сильно зависит от приложения.
«Предзагрузка всего на свете» может быть простейшей стратегией, но совсем не обязательно лучшей. Также,
предзагрузка будет работать только в случае, когда PHP работает в режиме обслуживания запросов без перезагрузки.
Таким образом, хоть предзагрузку и можно использовать в режиме CLI с включённым opcache, но в большинстве
случаев бессмысленно. Исключением является использование предзагрузки с
библиотеками FFI.
Замечание:
Предзагрузка не поддерживается в Windows.
Настройка предзагрузки состоит из двух этапов и требует включённого opcache.
Для начала, настройте opcache.preload
в php.ini:
Файл preload.php — это обязательный файл, который будет запущен один раз при старте сервера
(PHP-FPM, mod_php, etc.) и который загрузит код в постоянную память. В серверах, которые запускаются от имени root
перед переключением на непривилегированного пользователя системы или если PHP запускается от имени root (не рекомендуется),
значение opcache.preload_user может указывать системного пользователя
для запуска предварительной загрузки.
Запуск предварительной загрузки от имени root по умолчанию запрещён.
Установите opcache.preload_user=root
, чтобы явно разрешить это.
В скрипте preload.php любой файл, указанный в выражениях include,
include_once, require, require_once или
opcache_compile_file(), будет загружен в постоянную память. В следующем примере
будут загружены все файлы .php в директории src, если они не содержат
Test
в имени.
И include и opcache_compile_file() будут работать, но при этом
будут немного по разному обработаны.
- Выражение include запустит код из файла, а
opcache_compile_file() нет. Это повлияет только на условные декларации
(функции объявленные в блоках if).
- Из за того, что include запустит код, вложенные include
также будут обработаны и предзагружены.
- Функция opcache_compile_file() может загружать файлы в любом порядке. То есть, если
файл a.php определяет класс
A
и b.php определяет класс
B
, который является наследником A
, то функция opcache_compile_file() может
загрузить эти два файла в любом порядке. При использовании выражения include, с другой стороны, файл a.php
должен быть загружен первым.
- В любом случае, если какой-то скрипт в последствии запросит включение уже предзагруженного скрипта, то он будет
выполнен, но сущности пересоздаваться не будут. Использование выражения include_once не предотвратит повторное
включение файла. Может потребоваться загрузить файл снова,
чтобы включить в него определённые глобальные константы, поскольку
они не обрабатываются предварительной загрузкой.
Какой подход использовать — зависит от желаемого поведения. Для кода, который использует автозагрузчик, подход с
вызовом функции
opcache_compile_file() даст больше гибкости. С кодом, который будет загружаться вручную,
вариант с выражением
include может быть более надёжным.