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