Класичний PHP працює за моделлю «нічого не спільного» (shared-nothing): кожен запит починає з чистого аркуша.
Життєвий цикл запиту:
- Веб-сервер (Nginx, Caddy) передає запит у PHP-FPM.
- Вільний воркер FPM запускає скрипт-точку входу (
public/index.php). - Підключається автозавантажувач, створюється застосунок, завантажується конфігурація, реєструються сервіс-провайдери - на кожному запиті заново.
- Обробляється запит, формується відповідь.
- Після відповіді уся пам'ять звільняється: змінні, об'єкти, з'єднання (крім постійних), статичні властивості.
Що з цього випливає:
- Витоки пам'яті майже не шкодять: усе звільниться в кінці запиту.
- Стан між запитами живе лише зовні: в базі, кеші (Redis), сесії, файлах. Статична змінна, змінена в одному запиті, у наступному знову має початкове значення.
- Помилка в одному запиті не впливає на інші - кожен ізольований.
- Ціна - повторна ініціалізація. Завантажити фреймворк з сотнями класів на кожен запит дорого. Частково це компенсують OPcache (готовий байт-код) і кешування конфігурації й маршрутів (
php artisan optimize).
Інша модель - довгоживучі воркери (Laravel Octane на FrankenPHP, RoadRunner чи Swoole): застосунок завантажується один раз і обслуговує тисячі запитів. Це швидше, але стан зберігається між запитами: статичні властивості, синглтони, кеш у пам'яті сервісу. Код, написаний з розрахунку на shared-nothing, може «протікати» даними одного користувача в запит іншого.