Кожне налаштування — одна змінна середовища
Кожне налаштування — це змінна середовища (плюс один необовʼязковий файл, .oxphpdeny, для правил заборони шляхів), і кожна змінна має значення за замовчуванням, придатне для production. Розгорніть застосунок із порожнім середовищем, а потім перевизначте лише ті змінні, які для вас справді важливі.
Будь-яке значення поза цим набором — наприклад, описка на кшталт «ture» — одразу спричиняє помилку під час запуску з назвою змінної. Порожнє значення рівнозначне незаданому: підстановки FOO=${FOO}, що дають FOO=, повертаються до значення за замовчуванням, а не зупиняють запуск.
Сервер і воркери
15 зміннихАдреса й порт основного HTTP-сервера.
Коренева тека для віддавання файлів і PHP-скриптів.
Єдиний канонічний вхідний скрипт. Не задано — пряме зіставлення файлів, *.php — фронт-контролер, не .php — SPA-fallback; у режимі воркерів — bootstrap воркера. Шлях відраховується від DOCUMENT_ROOT.
Увімкнути постійний режим воркерів. Потрібен ENTRY_FILE, що вказує на .php-скрипт.
Максимум одночасних TCP-зʼєднань. Також верхня межа для типового QUEUE_MAX_WAITING (половина від нього); некоректне значення — помилка запуску. Тримайте його вищим за PHP_WORKERS + QUEUE_CAPACITY + QUEUE_MAX_WAITING.
Потоки асинхронного введення-виведення. 1 — однопотоковий режим, N — фіксована кількість, не задано — автоматично. Ділить ядра з PHP_WORKERS — підняття до повної кількості ядер зазвичай знижує пропускну здатність. CPU — це кількість ядер, на яких процесу дозволено виконуватися (маска affinity, знижена до квоти cgroup), а не вага CPU чи ліміт, який платформа застосовує поза контейнером; що саме пораховано, показує рядок CPU count for default sizing під час запуску.
Бекенд виконання PHP: sapi — справжній PHP, stub — для бенчмарків без PHP.
Розмір пулу воркерів. N — фіксований пул, MIN:MAX — динамічне масштабування, 0 — автоматично. Автоматичне визначення розміру рахує CPU так само, як TOKIO_WORKERS: на тарифі, ліміт CPU якого контейнер не бачить (cpu_source: host у журналі запуску), задайте обидві змінні явно.
Скільки секунд динамічний воркер простоює, перш ніж його буде виведено з пулу. Виведення чекає моменту, коли нічого не виконується, тож запити в процесі обробки ніколи не обриваються.
Максимум запитів в очікуванні в черзі PHP; запити, що надходять до заповненої черги, чекають до QUEUE_WAIT_TIMEOUT_MS. 0 — автоматично. Для пулів MIN:MAX початкова кількість воркерів дорівнює мінімуму.
Верхня межа того, скільки запит може чекати на PHP-воркер до відповіді 529, — один дедлайн на очікування місця в черзі й у самій черзі. Під перевантаженням сервер сам його скорочує (до 1/64, мінімум 10 мс); чинне значення показує oxphp_admission_wait_budget_us. 0 — відхиляти, щойно черга заповнилася.
Максимум запитів, що чекають на місце в черзі; понад це — негайна 529. Кожен такий запит утримує зʼєднання та своє буферизоване тіло. 0 — автоматично.
Максимум байтів тіл запитів, які утримує множина очікування; запит, чиє тіло перевищило б його, отримує негайну 529, запити без тіла чекають далі. 0 — автоматично.
Межа памʼяті на воркер у MiB, після якої його перезапускають. 0 — без обмежень. Воркери також перезапускаються після трьох поспіль запитів, що завершилися збоєм, або на вимогу через Worker::scheduleExit().
Будувати $_SERVER і $_GET перед кожним скриптом. Хибне значення пропускає цю роботу; $_POST, $_FILES, $_COOKIE і php://input це не зачіпає.
Трафік і доставка
18 зміннихМаксимум секунд на отримання HTTP-заголовків після підключення (захист від Slowloris).
Максимум секунд на завершення поточних запитів під час плавної зупинки; після цього запити, що залишилися, скасовуються. Запит, що завис у блокувальному виклику, може утримувати процес і довше.
Максимум запитів з однієї IP-адреси за вікно. 0 — вимкнено; заповнена черга PHP відповідає 529.
Тривалість вікна обмеження частоти в секундах.
Шлях до PEM-сертифіката. Щоб увімкнути TLS, мають бути задані і TLS_CERT, і TLS_KEY.
Шлях до приватного ключа PEM.
Мінімальна версія TLS: 1.2 або 1.3. Перевіряється під час запуску, навіть коли TLS вимкнено.
Максимум одночасно відкритих потоків на одне зʼєднання.
Максимум фреймів RST_STREAM у черзі, після якого зʼєднання закривається (захист від Rapid Reset).
Максимальний сумарний обсяг декодованих заголовків на запит у байтах.
Інтервал між фреймами PING у секундах; 0 вимикає.
Скільки секунд чекати на відповідь на PING, перш ніж закрити зʼєднання.
Cache-Control: max-age для статичних файлів. Приймає 30s, 5m, 2h, 30d, 1w, 1y, число секунд або off. Замінює STATIC_CACHE_TTL.
Повторна перевірка mtime для кешу в памʼяті — не частіше ніж раз на 3 с для кожного файлу. Замінює STATIC_CACHE.
Запропоновані кодування вмісту: br, zstd, gzip. off/none вимикає стиснення. Порядок ігнорується — кешовані статичні файли віддають перевагу Brotli, усе інше — zstd.
Якість Brotli 0–11; 0 прибирає Brotli. Замінює COMPRESSION_LEVEL (чиє значення 0 і досі вимикає всі кодування).
Рівень Zstandard 0–19; 0 прибирає zstd. Значення поза діапазоном зупиняють запуск.
Рівень gzip 0–9; 0 прибирає gzip. Значення поза діапазоном зупиняють запуск.
Безпека
5 зміннихЗахист від клікджекінгу: SAMEORIGIN, DENY або off. Встановлює X-Frame-Options + CSP frame-ancestors на кожній відповіді; заголовки, задані застосунком, завжди мають пріоритет. Некоректні значення повертаються до SAMEORIGIN із попередженням під час запуску.
Довірені проксі: розділений комами перелік, що поєднує CIDR, окремі IP-адреси та ключові слова private і cloudflare. Справжня IP-адреса клієнта береться з Forwarded / X-Forwarded-* за правилом «крайня права недовірена»; з cloudflare — з CF-Connecting-IP, коли запит пройшов через edge-вузол Cloudflare.
Glob-шаблони, .php-файли за якими ніколи не виконуються через прямий URI (/uploads/**). Зіставлення відбувається до звернення до диска — без оракула існування файлу.
Відповідь у разі збігу з PHP_DENY_PATHS або з правилом заборони .oxphpdeny: HTTP-статус 400–599 або резервний PHP-скрипт із префіксом / всередині DOCUMENT_ROOT. У режимі воркерів правила заборони .oxphpdeny приймають лише код статусу.
Абсолютні шляхи, під якими символьні посилання можуть виходити за межі DOCUMENT_ROOT. Не задано — вихід заборонено.
Логи, трасування та профілі
39 зміннихДокладність власної діагностики сервера: trace, debug, info, warn, error. Не фільтрує журнал доступу; розриви зʼєднань клієнтами логуються на рівні debug.
Журнал доступу для кожного запиту: all — усі запити, error — лише 4xx/5xx, не задано — вимкнено.
Внутрішній сервер (/health, /metrics, /config). Значення лише з портом привʼязуються до 127.0.0.1; не задано — не запускається.
Список дозволених CIDR для внутрішнього сервера; стороннім — 403, проби здоровʼя лишаються доступними. Loopback не дозволено неявно.
Тека з власними сторінками помилок {status}.html.
Максимальний розмір тіла для внутрішніх ендпоінтів запитів у байтах (512 KiB).
Поширення W3C Trace Context: зчитує traceparent/tracestate і передає їх у PHP через $_SERVER.
Увімкнути експорт спанів OpenTelemetry. Передбачає TRACE_CONTEXT=true.
Протокол експорту: grpc або http/protobuf.
Ендпоінт OTLP-колектора. З http/protobuf це базовий URL: спани надсилаються на /v1/traces під ним.
Тайм-аут експорту в мілісекундах. Через gRPC він також обмежує підключення до колектора, включно з рукостисканням TLS, а на Linux визначає, як швидко закривається зʼєднання, що перестало приймати дані.
Заголовки автентифікації: key=value,key2=value2.
Назва сервісу в експортованих спанах.
Атрибут версії сервісу.
Додаткові атрибути ресурсу: env=prod,region=us-east-1.
Стратегія семплювання: always_on, always_off, traceidratio та варіанти parentbased_*.
Частка семплювання 0.0–1.0 для семплерів на основі частки; значення поза діапазоном обрізаються до меж.
APM: автоінструментування 34 PHP-функцій (PDO, mysqli, cURL, Redis…), перехоплення помилок, SDK трасування. Потребує OTEL_ENABLED. Коли вимкнено, oxphp_apm_trace() однаково виконує свій колбек.
Поріг повільного запиту в мс; повільніші запити до БД отримують oxphp.db.slow=true.
Записувати параметри привʼязки в спани db.params. Вони записуються як є (без маскування), тож у трасування можуть потрапити персональні дані — вмикайте лише там, де це прийнятно.
Обмеження атрибута exception.stacktrace; обрізається з кінця. 0 — без обрізання.
Обмеження атрибута exception.message (ліміт New Relic на один атрибут); обрізається з кінця. 0 — без обрізання.
Головний перемикач. Інші змінні PROFILER_* однаково розбираються, тож помилки в них виявляються під час запуску.
Імовірність 0.0–1.0, що запит потрапить у вибірку.
Також семплювати запити до внутрішнього сервера.
Секрет, який мають містити явні тригери (заголовок X-OxPHP-Profile, кука OXPROF, параметр запиту __oxprof), і bearer-токен для /__profiler/*. Не задано — без токена. Семплювання та функції OxPHP\Profile\* його ніколи не перевіряють.
Обмеження кількості спанів на запит; довші профілі обрізаються.
Максимальна глибина вкладеності записаних викликів; час глибших викликів додається до виклику на межі. Обмежується значенням 32.
Тека для профілів на диску.
Формати, що записуються на диск: xhprof, speedscope, pprof, flamegraph.
Обмеження кількості файлів профілів, записаних за секунду.
Максимум збережених файлів профілів; старіші видаляються.
Віддалений ендпоінт, куди профілі надсилаються через POST.
Формат передавання для експорту.
Bearer-токен, що надсилається з кожним експортом.
Обгортка, сумісна з XHGui; не задано — автовизначення за URL.
Конверт Buggregator (завжди xhprof); не задано — автовизначення за URL. Взаємовиключний із PROFILER_EXPORT_XHGUI.
app_name для Buggregator, щоб групувати за проєктами.
Теги Buggregator: key=value,key2=value2. Некоректні токени — помилка запуску.
Асинхронність і спільний стан
18 зміннихОпційні заміни блокувальних вбудованих функцій, що призупиняють файбер. Категорії: sleep (нативні sleep/usleep), streams (блокувальні читання tcp:// і stream_select), net (встановлення зʼєднань, рукостискання й читання TLS, записи, що чекають на місце в буфері, читання unix:// / udp:// / udg:// — потребує streams, лише Linux). 1/true/all — усі категорії. Встановлений набір видно як runtime_hooks у /config.
Виділені потоки асинхронних воркерів. 0 — функції зареєстровано, але під час виклику вони кидають AsyncException.
Максимум завдань в очікуванні в асинхронній черзі. 0 — автоматично.
Обмеження кількості одночасних файберів завдань на воркер; загальна межа одночасних завдань = файбери × воркери.
Головний перемикач усієї підсистеми OxPHP\Shared\*. Вимкнено — її класи взагалі не реєструються; перевіряйте через class_exists().
Загальне обмеження кількості живих обʼєктів Shared (ключі Map не враховуються); створення обʼєкта понад нього кидає CapacityException.
Загальне обмеження оціненої памʼяті всіх обʼєктів Shared, перевіряється лише під час створення обʼєкта.
Вмикає й вимикає експонування метрик Prometheus oxphp_shared_*.
Вмикає й вимикає API інтроспекції /__ox_shared/*.
Попередній перегляд значень у відповідях інтроспекції; вимкніть, якщо він може розкрити дані.
Глибина BFS для перевірки циклів; збільште для глибоких графів.
Кількість ребер, що обходяться під час перевірки циклів; збільште для щільних графів.
Обмеження розміру одного значення; більші вставки одразу завершуються помилкою.
Обмеження сумарного обсягу даних на канал.
Детектор взаємоблокувань для Shared\Mutex: off, warn (логувати й рахувати цикли) або strict (розривати їх через DeadlockException). У debug-збірках типово strict.
Як часто детектор взаємоблокувань сканує, у мс.
Обрізання кожного рядка в попередньому перегляді, у байтах, по межі символу.
Кількість елементів у вибірці для попереднього перегляду /entry.
Приклади конфігурацій
Відправні точки просто з документації — скопіюйте одну й підлаштуйте під себе.
Коли внутрішній сервер запущено, /config повертає підсумкову конфігурацію у форматі JSON. Шляхи до TLS, INTERNAL_ADDR та ERROR_PAGES_DIR у відповіді приховано.
Нульова конфігурація — теж конфігурація
Кожне значення за замовчуванням вище дібране так, щоб порожнє середовище просто працювало.