OPcache і JIT
OPcache працює з OxPHP одразу, без додаткових дій. Усі робочі потоки PHP спільно використовують один сегмент пам’яті OPcache. Скрипти компілюються один раз під час першого виконання, а далі кожен робочий потік отримує їх із кешу. Щоб увімкнути це спільне використання, нічого спеціально налаштовувати не потрібно.
Як OPcache працює з OxPHP
OxPHP реєструється як іменований SAPI, і OPcache поводиться з ним так само, як з іншими серверними SAPI. Основні особливості:
- Спільний кеш для всіх робочих потоків: усі робочі потоки PHP використовують той самий кеш скомпільованих опкодів. Один потік компілює файл — виграють усі.
- Жодної компіляції на кожен запит: після першого запиту до кожного скрипту наступні запити повністю пропускають етап розбору й компіляції.
opcache.enable_cliне впливає на OxPHP. Цей параметр стосується лише SAPI з назвамиcliіphpdbg. OxPHP реєструється з назвою SAPIcli-server, тож OPcache керується виключно черезopcache.enable. Параметрopcache.enable_cliкорисний, якщо ви запускаєте PHP CLI в тому самому контейнері (наприклад, для міграцій або команд Artisan). Офіційний образ OxPHP постачає PHP CLI разом із бінарним файлом сервера, тож ви можете встановитиopcache.enable_cli=1, якщо вашим CLI-скриптам кешування піде на користь.
Щоб увімкнути OPcache, достатньо мінімум:
[opcache]
opcache.enable=1Офіційний Docker-образ OxPHP побудовано на php:*-zts-alpine, де OPcache статично вкомпільовано в бінарний файл PHP. НЕ додавайте zend_extension=opcache до свого INI-файлу. Розширення вже завантажене, і цей рядок спричинятиме попередження під час кожного запуску PHP. Потрібна лише секція конфігурації [opcache].
Рекомендовані налаштування для продакшну
Ці налаштування оптимізовано для розгортання в контейнерах у продакшні, де PHP-файли не змінюються під час роботи. Для максимальної пропускної здатності вимкніть перевірку часових позначок. Щоб також компілювати файли під час запуску, додайте два параметри з розділу Попереднє завантаження.
[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=0
opcache.revalidate_freq=0
opcache.file_update_protection=0
opcache.jit_buffer_size=64M
opcache.jit=tracing| Параметр | Рекомендоване значення | Опис |
|---|---|---|
memory_consumption |
128 |
Спільна пам’ять у МБ для скомпільованих скриптів. Збільште, якщо opcache_get_status() показує замало вільної пам’яті. |
interned_strings_buffer |
16 |
Пам’ять у МБ для інтернованих рядків, спільних для всіх робочих потоків. |
max_accelerated_files |
10000 |
Максимальна кількість кешованих скриптів. Установіть значення, більше за загальну кількість ваших файлів .php. |
validate_timestamps |
0 |
Зі значенням 0 OPcache ніколи не перевіряє файлову систему на зміни. Щоб підхопити зміни коду, перезапустіть контейнер або викличте opcache_reset(). |
revalidate_freq |
0 |
Кількість секунд між перевірками файлової системи. Не діє, коли validate_timestamps=0. |
file_update_protection |
0 |
Скільки секунд після зміни файлу має минути, перш ніж його можна кешувати. Установіть 0, щоб кешувати одразу під час запуску. |
Налаштування для розробки
Для розробки ввімкніть перевірку часових позначок, щоб зміни коду набували чинності без перезапуску контейнера. Вимкніть JIT, щоб під час налагодження отримувати зрозуміліші трасування стека.
[opcache]
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.validate_timestamps=1
opcache.revalidate_freq=2
opcache.jit_buffer_size=0
opcache.jit=disableІз validate_timestamps=1 OPcache перевіряє час зміни файлів кожні revalidate_freq секунд. Це додає невеликі накладні витрати на кожен запит, зате дає змогу редагувати PHP-файли й бачити зміни на першому запиті після цього інтервалу.
Це рекомендована стратегія перезавантаження коду в режимі розробки для OxPHP. OPcache перевіряє часову позначку включеного файлу щонайбільше раз на revalidate_freq секунд, тож зміни коду підхоплюються, щойно мине це вікно, без перезапуску контейнера й без зовнішнього демона для відстеження файлів. Використовуйте revalidate_freq=0 для негайної перевірки під час кожного включення (найвища точність, трохи більше вводу-виводу) або revalidate_freq=2, щоб розподілити вартість перевірок. Наведене вище значення за замовчуванням — вдалий компроміс, особливо якщо ваш DOCUMENT_ROOT розташовано на повільному bind-монтуванні (Docker на macOS/Windows).
Що НЕ перезавантажується через validate_timestamps
Деякі види змін усе одно потребують перезапуску контейнера (або перезапуску робочого процесу) навіть із validate_timestamps=1:
- Попередньо завантажені файли (
opcache.preload) під’єднуються до сервера під час запуску й ніколи не перевіряються повторно. Змінили попередньо завантажений файл — перезапустіть контейнер. - Стан ініціалізації Worker Mode — у Worker Mode автозавантажувач, DI-контейнер і будь-які об’єкти, створені в зовнішній області видимості, живуть у пам’яті робочого процесу. OPcache перекомпілює змінені файли класів, але робочий процес не виконає свою ініціалізацію повторно. Для циклів робочих процесів під час розробки викликайте
Worker::scheduleExit()наприкінці кожного запиту (наприклад, за прапорцем середовищаOXPHP_DEV), щоб перезапустити робочий процес: він знову виконає зовнішню область видимості й підхопить усі зміни. - Кеші на рівні фреймворку — скомпільований контейнер Symfony, кеш маршрутів/конфігурації/представлень Laravel, оптимізована карта класів Composer. Це файли
.php, які OPcache перевіряє повторно, але значення в них посилаються на застарілі шляхи класів або ідентифікатори контейнера. Виконайте команду фреймворкуcache:clear; самого OPcache недостатньо. - Не-PHP файли —
.env,composer.json, конфігурація YAML/JSON, файли шаблонів, що компілюються поза OPcache. OPcache відстежує лише файли, які сам скомпілював; усе інше потребує перезапуску.
JIT-компіляція
JIT-компілятор OPcache перетворює опкоди PHP на нативний машинний код під час виконання. Для найкращої оптимізації використовуйте режим tracing:
opcache.jit=tracing
opcache.jit_buffer_size=64MJIT дає найбільший виграш для PHP-коду, обмеженого процесором: циклів з інтенсивною математикою, обробки рядків, роботи із зображеннями та рендерингу шаблонів. Для застосунків, обмежених вводом-виводом, які більшу частину часу чекають на запити до бази даних чи виклики зовнішніх API, покращення мінімальне.
Щоб вимкнути JIT:
opcache.jit=disable
opcache.jit_buffer_size=0Попереднє завантаження
Попереднє завантаження OPcache компілює й кешує PHP-файли під час запуску сервера, ще до обробки будь-яких запитів. Це повністю усуває вартість компіляції на першому запиті й робить класи та функції доступними глобально без жодних накладних витрат на require чи автозавантаження.
Налаштуйте попереднє завантаження у своєму INI-файлі:
opcache.preload=/var/www/html/preload.php
opcache.preload_user=www-dataСтворіть скрипт preload.php, який завантажує файли, що використовуються найчастіше:
<?php
// preload.php — runs once at server startup
require __DIR__ . '/vendor/autoload.php';
// Preload framework core files
$files = glob(__DIR__ . '/vendor/symfony/http-kernel/**.php');
foreach ($files as $file) {
opcache_compile_file($file);
}
// Preload hot application paths
opcache_compile_file(__DIR__ . '/src/Controller/ApiController.php');
opcache_compile_file(__DIR__ . '/src/Service/UserService.php');Попередньо завантажені класи й функції постійно доступні для всіх запитів. Змінити їх без перезапуску сервера неможливо.
Якщо ви використовуєте Worker Mode, ваш застосунок і так ініціалізується один раз: автозавантажувач, конфігурація та з’єднання з базою даних зберігаються між запитами. Попереднє завантаження OPcache доповнює це, усуваючи накладні витрати на компіляцію опкодів, але не замінює ініціалізацію застосунку. Ці два механізми працюють незалежно й можуть використовуватися разом.
Застосування конфігурації PHP
OxPHP читає конфігурацію PHP зі стандартного каталогу conf.d. Щоб передати власний INI-файл, використайте Docker-том або інструкцію COPY.
docker run -p 80:80 \
-v ./custom.ini:/usr/local/etc/php/conf.d/custom.ini:ro \
ghcr.io/oxphp/oxphp:0.13.0FROM ghcr.io/oxphp/oxphp:0.13.0
COPY custom.ini /usr/local/etc/php/conf.d/custom.ini
COPY --chown=www-data:www-data . /var/www/htmlservices:
app:
image: ghcr.io/oxphp/oxphp:0.13.0
ports:
- "80:80"
volumes:
- ./custom.ini:/usr/local/etc/php/conf.d/custom.ini:ro
- ./src:/var/www/htmlМоніторинг стану кешу
Щоб переконатися, що OPcache працює, перевірте його поточний стан із PHP:
<?php
$status = opcache_get_status();
echo "Cached scripts: " . $status['opcache_statistics']['num_cached_scripts'] . "\n";
echo "Cache hits: " . $status['opcache_statistics']['hits'] . "\n";
echo "Cache misses: " . $status['opcache_statistics']['misses'] . "\n";
echo "Free memory: " . $status['memory_usage']['free_memory'] . " bytes\n";Якщо free_memory постійно низьке, збільште opcache.memory_consumption.
Промпти для вашого агента
Ці промпти розраховані на агента з під’єднаним MCP-сервером документації OxPHP — потрібні сторінки він прочитає сам.
Налаштуй OPcache під фактичний обсяг коду цього репозиторію та під те, як збирається його образ. Прочитай сторінку `php/opcache` через MCP-сервер документації OxPHP.
Порахуй файли `.php`, які постачає цей проєкт, щоб визначити `max_accelerated_files` і `memory_consumption`, і вибери `validate_timestamps` залежно від того, чи мій Dockerfile вбудовує код в образ, чи його накладає bind-монтування під час виконання.Дивіться також
- Посібник із Docker -- налаштування контейнера й монтування файлів конфігурації
- Довідник конфігурації -- змінні середовища для OxPHP
- Worker Mode -- постійні робочі процеси PHP, яким OPcache приносить найбільше користі