Modo clásico
El modo clásico ejecuta un front controller de PHP normal y corriente —el mismo public/index.php al que ya apuntas con php-fpm— desde cero en cada petición que llega. Rapira ocupa el lugar de php-fpm y la aplicación no necesita ningún cambio: las superglobales se rellenan, el script se ejecuta de arriba abajo y lo que imprima se convierte en la respuesta.
Estado limpio en cada petición
Cada petición pasa por un ciclo de PHP completo: arranque de la petición, tu script de entrada y cierre de la petición. Todo lo que el script haya construido por el camino —variables globales, propiedades estáticas, el contenedor de DI, el mapa de identidad del ORM— se destruye antes de que empiece la siguiente, exactamente igual que bajo php-fpm.
Un descriptor que se escapa, un singleton que se queda inicializado a medias, una biblioteca que se guarda datos de la petición en una propiedad estática: nada de eso afecta a la petición siguiente, porque nada de lo que crea tu script sobrevive a la petición en la que se creó. Valen las mismas excepciones que con php-fpm: las conexiones persistentes y el estado que vive dentro de una extensión están en el proceso worker, no en la petición. El código que nunca se escribió pensando en un proceso de larga vida funciona aquí sin cambios. fastcgi_finish_request() viene del binario de php-fpm y no está disponible bajo Rapira, que ofrece rapira_finish_request() con el mismo contrato —enviar la respuesta al cliente cuanto antes y seguir trabajando después—, documentada en la página de HTTP.
La aplicación vuelve a arrancar en cada petición: autoloader, configuración, contenedor, rutas. Consulta la página de modos de ejecución para más información.
Cómo activarlo
Hay dos maneras de elegir el modo, y las dos hacen lo mismo:
--classicen la línea de comandos, junto al script de entrada.classic = trueen la sección[pool]de unrapira.toml.
La opción solo sirve para activar el modo: no existe --no-classic, así que un archivo de configuración con classic = true se queda en clásico diga lo que diga la línea de comandos. En todo lo demás manda la precedencia de siempre, en la que las opciones de línea de comandos ganan al archivo de configuración; la lista completa de claves está en la página de configuración.
Un script de entrada clásico es PHP normal:
<?php
// index.php
header('Content-Type: text/plain');
echo "Hello, " . ($_GET['name'] ?? 'anonymous') . "!\n";
echo "Method: {$_SERVER['REQUEST_METHOD']}\n";Apunta Rapira hacia él de cualquiera de las dos formas:
rapira serve --classic public/index.php[pool]
entrypoint = "public/index.php"
classic = trueCon el archivo de configuración, el comando para arrancar es rapira serve --config rapira.toml. Un pool.entrypoint relativo se resuelve respecto al directorio del propio archivo de configuración, así que puedes mover el archivo de sitio sin romper nada; una ruta de script relativa en la línea de comandos se resuelve respecto al directorio actual. El resto de opciones están en la referencia de la línea de comandos.
Script de entrada
Rapira no traduce URLs a archivos del disco ni sirve nada del disco por su cuenta. Cada petición ejecuta el script de entrada que le indicaste, venga la ruta que venga, y la URL llega en $_SERVER['REQUEST_URI'] para que la enrute tu aplicación.
De ahí salen las variables CGI: SCRIPT_FILENAME es siempre el script de entrada, SCRIPT_NAME su nombre de archivo con una barra delante (/index.php) y DOCUMENT_ROOT el directorio donde está. Los archivos estáticos necesitan algo por delante de Rapira: una CDN o el proxy inverso que monta la página de puesta en producción.
OPcache
Ejecutar desde cero reinicia el estado de tu aplicación, no el bytecode compilado. El proceso maestro arranca PHP una sola vez, al iniciar el módulo y antes de hacer fork de ningún worker, así que OPcache crea su segmento de memoria compartida una única vez y todos los workers heredan ese mismo mapeo. Con OPcache activado, los scripts compilados siguen en caché de una petición a otra y en todo el pool: volver a ejecutar tu front controller no significa volver a parsearlo.
El pool de procesos en sí es el mismo en los dos modos: el maestro hace fork de los workers y cada worker atiende una petición cada vez, así que la concurrencia sale del número de procesos. Consulta la página de modelo de procesos para más información sobre el proceso maestro y sus workers.
Rapira\create_plugin_handler() lanza una Rapira\RapiraException en modo clásico: plugin handlers require worker mode. No hay ningún bucle residente al que entregarle un handler, porque el script termina cuando termina la petición. Los scripts de worker son cosa del modo SAPI Worker.
Elegir entre Classic y SAPI Worker
Usa el modo clásico cuando el estado de tu aplicación no sobreviva a una segunda petición —código antiguo, un framework que se filtra en propiedades estáticas, una biblioteca de terceros que no controlas— o cuando estés migrando desde php-fpm y prefieras cambiar una cosa cada vez. Usa el modo SAPI Worker cuando tu código aguante un proceso que no muere y quieras quitar de en medio el arranque de cada petición. La página de modos de ejecución describe los cuatro modos, de los que Classic y SAPI Worker son los disponibles hoy.