Новое в Symfony 4.4: Предварительная загрузка приложений Symfony в PHP 7.4

PHP 7.4 был выпущен несколько дней назад, и это самый захватывающий релиз PHP за последние годы. Он включает в себя изменяющие игру функции, такие как типизированные свойства, функции стрелок, ковариантные типы, FFI (интерфейс внешних функций), предварительную загрузку OPCache и многое другое.

OPCache предварительная загрузка

В самом начале PHP анализировал и компилировал любой файл, используемый для обработки запроса. Результат анализа/компиляции (называемый «кодами операций») не использовался повторно для других запросов, поэтому один и тот же процесс должен был повторяться снова и снова.

На производственных серверах код ваших PHP-файлов не меняется между запросами, поэтому результаты анализа и компиляции можно использовать повторно. Это то, что делает OPCache (OPCache — “кэш opcodes”), повышая общую производительность от 2 до 15 раз.

Однако OPCache не снимает другие затраты на выполнение: PHP по-прежнему должен проверять, был ли изменен исходный файл, копировать определенные части классов и функций из кэша общей памяти в память процесса и т. д. Кроме того, поскольку каждый файл PHP является скомпилированный/кэшированный полностью независимо от любого другого файла, PHP не может разрешать зависимости между классами, хранящимися в разных файлах, и должен повторно связывать зависимости классов во время выполнения по каждому запросу.

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

Все функции и классы, определенные в этих файлах, будут доступны для запросов прямо из коробки, точно так же, как и внутренние объекты (например, strlen() или Exception). Фактически, PHP может предварительно загружать целые или частичные фреймворки, такие как Symfony, и даже всю библиотеку классов приложений.

OPCache предварительная загрузка на практике

Предварительная загрузка контролируется новой директивой php.ini под названием opcache.preload. Значением этой директивы является путь к файлу PHP, который предварительно загружает файлы с помощью include_once или opcache_compile_file().

Во время предварительной загрузки PHP также разрешает зависимости классов и связи с родителями, интерфейсами и признаками. Он также удаляет ненужные включения и выполняет некоторые другие оптимизации. Общий результат – повышение производительности на 30% -50% в реальных приложениях.

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

OPCache предварительная загрузка в Symfony

Благодаря внутреннему поведению Symfony при компиляции файлов перед запуском приложения (например, контейнера служб) мы можем внедрить поддержку предварительной загрузки только с несколькими изменениями. Вот почему Symfony 4.4 может сгенерировать файл предварительной загрузки для вашего приложения в каталоге кеша. Сгенерированное имя файла включает в себя как среду, так и имена ядра (например var/cache/dev/srcApp_KernelDevDebugContainer.preload.php).

Вы можете использовать этот сгенерированный файл как значение PHP-директивы opcache.preload:

; php.ini
opcache.preload=/path/to/project/var/cache/prod/srcApp_KernelProdContainer.preload.php

Следующим шагом будет разрешение приложениям и пакетам объявить, какие из их классов также должны быть предварительно загружены. Посмотрите запрос на извлечение №33689, чтобы увидеть функцию незавершенного производства, чтобы сделать это.

Если вы уже используете PHP 7.4, протестируйте эту функцию в своих реальных проектах и сообщите об улучшении производительности. Или, что еще лучше, опубликуйте пост в блоге с подробностями, и опубликуем его в следующем посте A Week of Symfony.