Skip to content

Классический режим

Классический режим выполняет обычный фронт-контроллер на PHP — тот самый public/index.php, на который вы уже направили php-fpm, — с нуля на каждый пришедший запрос. Rapira встаёт на место php-fpm, и приложение не требует изменений: суперглобальные переменные заполнены, скрипт отрабатывает сверху вниз, и всё, что он напечатал, становится ответом.

Чистое состояние на каждый запрос

Каждый запрос проходит полный цикл PHP: старт запроса, ваш входной скрипт, завершение запроса. Всё, что скрипт успел построить по дороге — глобальные переменные, статические свойства, DI-контейнер, карту объектов ORM, — разбирается до начала следующего запроса, ровно как под php-fpm.

Утёкший дескриптор, синглтон, инициализированный наполовину, библиотека, которая прячет данные запроса в статическом свойстве, — ничто из этого не влияет на следующий запрос, ведь созданное скриптом не переживает тот запрос, в котором было создано. Исключения ровно те же, что и у php-fpm: постоянные соединения и состояние внутри расширений живут в процессе воркера, а не в запросе. Код, который не рассчитан на долгоживущий процесс, работает здесь без изменений. Функция fastcgi_finish_request() приходит из бинарника php-fpm, и в Rapira её нет; вместо неё есть rapira_finish_request() с тем же контрактом — отдать ответ клиенту раньше времени и продолжить работу после этого, — она описана в разделе HTTP.

Приложение поднимается заново на каждый запрос: автозагрузчик, конфиг, контейнер, маршруты. Подробнее — в разделе Режимы выполнения.

Как включить

Выбрать режим можно двумя способами, и делают они одно и то же:

  • --classic в командной строке, рядом с входным скриптом.
  • classic = true в секции [pool] файла rapira.toml.

Флаг умеет только включать режим: --no-classic не существует, поэтому конфиг с classic = true останется классическим, что бы ни было в командной строке. В остальном действует обычный порядок: флаги сильнее файла конфигурации. Полный список ключей — в Конфигурации.

Входной скрипт для классического режима — это обычный PHP:

php
<?php
// index.php
header('Content-Type: text/plain');
echo "Hello, " . ($_GET['name'] ?? 'anonymous') . "!\n";
echo "Method: {$_SERVER['REQUEST_METHOD']}\n";

Направьте на него Rapira любым из двух способов:

bash
rapira serve --classic public/index.php
toml
[pool]
entrypoint = "public/index.php"
classic = true

С файлом конфигурации команда запуска выглядит так: rapira serve --config rapira.toml. Относительный pool.entrypoint считается от каталога самого файла конфигурации, поэтому конфиг можно спокойно переносить; а относительный путь к скрипту в командной строке считается от текущего каталога. Про остальные опции рассказывает Командная строка.

Входной скрипт

Rapira не сопоставляет URL с файлами на диске и сама по себе с диска ничего не отдаёт. Любой запрос, с каким бы путём он ни пришёл, выполняет тот входной скрипт, который вы указали, а сам URL попадает в $_SERVER['REQUEST_URI'] — дальше маршрутизацией занимается приложение.

Отсюда и значения CGI-переменных: SCRIPT_FILENAME — всегда входной скрипт, SCRIPT_NAME — его имя файла со слешем впереди (/index.php), а DOCUMENT_ROOT — каталог, в котором он лежит. Статику придётся отдавать чем-то, что стоит перед Rapira: сетью доставки контента или обратным прокси, настройку которого разбирает Запуск в продакшене.

OPcache

Выполнение с нуля сбрасывает состояние вашего приложения, но не скомпилированный байт-код. Мастер-процесс запускает PHP ровно один раз, на старте модуля, ещё до того, как форкнет первого воркера, поэтому OPcache создаёт свой сегмент разделяемой памяти единственный раз, и каждый форкнутый воркер наследует то же самое отображение. С включённым OPcache скомпилированные скрипты остаются в кеше и между запросами, и сразу на весь пул: выполнить фронт-контроллер заново не значит заново его разобрать.

Сам пул процессов в обоих режимах одинаковый: мастер форкает воркеров, каждый воркер обрабатывает по одному запросу за раз, а параллельность даёт количество процессов. Подробнее о мастер-процессе и его воркерах рассказывает Модель процессов.

В классическом режиме Rapira\create_plugin_handler() бросает Rapira\RapiraException: обработчики плагинов работают только в режиме воркера. Отдавать обработчик просто некуда — резидентного цикла нет, скрипт заканчивается вместе с запросом. Скриптам воркера место в режиме SAPI Worker.

Выбор между Classic и SAPI Worker

Используйте классический режим, когда состояние приложения не переживает второй запрос: старая кодовая база, фреймворк, который оставляет состояние в статических свойствах, чужая библиотека, которую вы не контролируете, — или когда вы уходите с php-fpm и хотите менять по одной вещи за раз. Используйте режим SAPI Worker, когда код выдерживает процесс, который не завершается, и вы хотите убрать загрузку приложения на каждом запросе. Все четыре режима описывает Режимы выполнения; из них сегодня готовы Classic и SAPI Worker.