Руководство по обработчикам PHP: FastCGI, Apache, Nginx и версии PHP

PHP — один из самых популярных языков для веб-разработки, но чтобы PHP-скрипты выполнялись на сервере, нужен посредник — обработчик, который связывает веб-сервер с интерпретатором PHP. От выбора и настройки этого обработчика напрямую зависит производительность, безопасность и стабильность вашего проекта.

В этой статье мы подробно разберём:

  • Что такое обработчик PHP и зачем он нужен.
  • Эволюцию от CGI к FastCGI и PHP-FPM.
  • Настройку FastCGI в Apache (mod_fcgid, proxy_fcgi).
  • Разницу между версиями PHP: native и alt (на примере 8.3.6).
  • Как работает связка Nginx + PHP-FPM с примерами конфигурации.
  • Практические рекомендации по выбору и настройке.

1. Что такое обработчик PHP и зачем он нужен

Веб-сервер (Apache, Nginx) умеет отдавать статические файлы (HTML, CSS, JS, изображения) напрямую. Но когда запрашивается PHP-файл, сервер не может его выполнить сам — он должен передать его интерпретатору PHP, получить результат и отдать его клиенту.

Обработчик PHP — это программный компонент (модуль или внешний процесс), который принимает запрос от веб-сервера, запускает PHP-скрипт, возвращает результат и управляет жизненным циклом PHP-процессов.

Существует несколько способов интеграции PHP с веб-сервером:

  • Модуль PHP (например, mod_php для Apache) — устаревший подход.
  • CGI (Common Gateway Interface) — классический, но неэффективный.
  • FastCGI — современный, высокопроизводительный протокол.
  • PHP-FPM (FastCGI Process Manager) — продвинутый менеджер процессов для FastCGI.

2. Эволюция: от CGI к FastCGI и PHP-FPM

2.1 CGI (Common Gateway Interface)

CGI — самый старый способ запуска PHP. При каждом запросе веб-сервер создаёт новый процесс PHP, который обрабатывает скрипт и завершается. Это очень ресурсоёмко: каждый запрос требует запуска нового процесса, загрузки PHP, инициализации, выполнения и завершения.

Недостатки CGI:

  • Высокое потребление памяти и CPU.
  • Медленная работа при большом количестве запросов.
  • Не подходит для высоконагруженных проектов.

Сегодня CGI почти не используется в продакшене.

2.2 FastCGI

FastCGI — это протокол, который решает проблему CGI, поддерживая постоянные (persistent) процессы. Вместо того чтобы создавать процесс на каждый запрос, FastCGI запускает пул процессов, которые живут долго и обрабатывают множество запросов последовательно.

Преимущества FastCGI:

  • Процессы переиспользуются, что экономит память и время.
  • Поддерживает различные языки (PHP, Python, Perl).
  • Может работать с разными веб-серверами (Apache, Nginx, Lighttpd).

Однако классический FastCGI не управляет процессами автоматически — нужен менеджер процессов.

2.3 PHP-FPM (FastCGI Process Manager)

PHP-FPM — это официальный менеджер процессов для PHP, который реализует протокол FastCGI. Он встроен в PHP начиная с версии 5.3.3 и является стандартным решением для всех современных проектов.

Возможности PHP-FPM:

  • Динамическое управление количеством процессов (в зависимости от нагрузки).
  • Перезапуск процессов после определённого числа запросов (защита от утечек памяти).
  • Поддержка пулов с разными настройками для разных сайтов.
  • Медленный лог для выявления проблемных скриптов.
  • Статусная страница для мониторинга.

Именно PHP-FPM мы будем настраивать и использовать в большинстве примеров.

3. FastCGI в Apache

Apache поддерживает FastCGI через несколько модулей. Рассмотрим два основных подхода.

3.1 mod_fcgid

mod_fcgid — это модуль Apache, который реализует клиент FastCGI. Он запускает внешние процессы-обработчики (например, PHP-FPM или обычный PHP CGI) и управляет ими.

Установка и включение:

Bash
# Ubuntu/Debian
sudo apt install libapache2-mod-fcgid
sudo a2enmod fcgid
sudo systemctl restart apache2

Настройка виртуального хоста для PHP через mod_fcgid:

Apache
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example/public

    <Directory /var/www/example/public>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    # Настройка обработчика PHP через mod_fcgid
    <FilesMatch "\.php$">
        SetHandler fcgid-script
        FCGIWrapper /usr/lib/cgi-bin/php8.3
        Options +ExecCGI
    </FilesMatch>
</VirtualHost>

Однако этот подход требует, чтобы PHP CGI был установлен и доступен по указанному пути. На практике mod_fcgid чаще используют с PHP-FPM через проксирование.

3.2 proxy_fcgi (Apache 2.4+)

Начиная с Apache 2.4, появился модуль mod_proxy_fcgi, который позволяет проксировать запросы к PHP-FPM через протокол FastCGI. Это более современный и гибкий способ.

Включение модулей:

Bash
sudo a2enmod proxy proxy_fcgi
sudo systemctl restart apache2

Настройка виртуального хоста для работы с PHP-FPM:

Apache
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/example/public

    <Directory /var/www/example/public>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    # Проксирование PHP-запросов к PHP-FPM
    <FilesMatch "\.php$">
        SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
    </FilesMatch>
</VirtualHost>

Объяснение:

  • proxy:unix:/run/php/php8.3-fpm.sock — указывает на Unix-сокет, который слушает PHP-FPM. Путь зависит от ОС и версии (в CentOS/RHEL может быть иначе, в Docker — тоже).
  • fcgi://localhost/ — протокол и адрес (хост не важен, используется для совместимости).
  • Всё вместе говорит Apache: «Передай запрос к .php файлу в PHP-FPM через Unix-сокет».

Этот способ предпочтительнее, так как он использует PHP-FPM со всеми его возможностями управления процессами.

3.3 Пример полной конфигурации Apache + PHP-FPM

Apache
<VirtualHost *:80>
    ServerName mysite.com
    ServerAlias www.mysite.com
    DocumentRoot /var/www/mysite/public

    ErrorLog ${APACHE_LOG_DIR}/mysite_error.log
    CustomLog ${APACHE_LOG_DIR}/mysite_access.log combined

    <Directory /var/www/mysite/public>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    # Обработка PHP через PHP-FPM
    <FilesMatch "\.php$">
        SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
    </FilesMatch>

    # Запрет доступа к скрытым файлам
    <FilesMatch "^\.">
        Require all denied
    </FilesMatch>
</VirtualHost>

4. Версии PHP: native и alt (на примере 8.3.6)

При установке PHP на сервере вы можете столкнуться с тем, что одна и та же версия доступна в разных вариантах: native и alt. Это особенно актуально для Debian/Ubuntu и сторонних репозиториев (например, ondrej/php).

4.1 Что такое native версия

Native — это версия PHP, которая поставляется в официальных репозиториях вашего дистрибутива Linux. Например, в Ubuntu 22.04 LTS по умолчанию доступен PHP 8.1. Он считается «родным» для этой ОС и полностью протестирован на совместимость.

Особенности native:

  • Устанавливается через стандартные пакеты (например, php8.1php8.1-fpm).
  • Получает обновления безопасности от разработчиков дистрибутива.
  • Может быть не самой свежей версией (Ubuntu обычно отстаёт на 1–2 года).
  • Гарантированно работает с остальными системными пакетами.

Пример установки native PHP 8.1 на Ubuntu:

Bash
sudo apt update
sudo apt install php8.1 php8.1-fpm php8.1-mysql php8.1-curl php8.1-gd php8.1-mbstring

4.2 Что такое alt (alternative) версия

Alt (alternative) — это версия PHP, установленная из стороннего репозитория, например, из PPA ondrej/php (для Ubuntu) или из репозитория Remi (для CentOS). Эти репозитории предлагают более свежие версии PHP, которые ещё не попали в официальные репозитории дистрибутива.

Особенности alt:

  • Устанавливается с суффиксом версии в имени пакета (например, php8.3php8.3-fpm).
  • Позволяет использовать последние возможности языка и исправления.
  • Может содержать бэкпорты безопасности, но не гарантирует полной совместимости с системой.
  • Позволяет одновременно установить несколько версий PHP.

Пример установки PHP 8.3.6 из PPA ondrej на Ubuntu:

Bash
# Добавление репозитория
sudo add-apt-repository ppa:ondrej/php
sudo apt update

# Установка PHP 8.3
sudo apt install php8.3 php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring

4.3 Разница между native и alt на практике

КритерийNative (например, 8.1)Alt (например, 8.3.6)
ИсточникОфициальный репозиторий дистрибутиваСторонний репозиторий (ondrej, Remi)
ВерсияОтстаёт на 1–2 релизаПоследняя стабильная
ОбновленияТолько критические исправления безопасностиЧастые обновления до мажорных версий
СтабильностьВысокая (проверена)Хорошая, но зависит от мейнтейнера
СовместимостьС другими системными пакетамиМожет требовать дополнительных зависимостей
Несколько версийТолько одна версия на системуМожно установить несколько версий параллельно

Практический совет: если ты на Ubuntu LTS и не гонишься за новыми фичами — бери native. Если нужен PHP 8.3+ или несколько версий параллельно — ставь alt (ondrej/php). Для VPS на Рег.ру чаще всего удобнее alt, чтобы быстро получать свежие версии и изолировать проекты пулами.

Когда выбирать native:

  • Вам важна максимальная стабильность и совместимость с системой.
  • Ваш проект не требует новейших функций PHP.
  • Вы используете LTS-версию дистрибутива и не хотите рисковать.

Когда выбирать alt:

  • Вам нужны новые возможности PHP (например, атрибуты, JIT, новые функции).
  • Вы используете фреймворки, которые требуют PHP ≥ 8.3.
  • Вы хотите установить несколько версий PHP для разных проектов на одном сервере.

4.4 Управление несколькими версиями PHP

Если у вас установлены несколько версий PHP (например, 8.1 и 8.3), вы можете выбрать, какую использовать для конкретного сайта через настройку пула PHP-FPM и конфигурации веб-сервера.

Создание отдельного пула для версии 8.3:

Bash
# Файл /etc/php/8.3/fpm/pool.d/myapp.conf
[myapp]
user = www-data
group = www-data
listen = /run/php/php8.3-myapp.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 10

Затем в конфигурации веб-сервера укажите этот сокет:

Apache:

Apache
<FilesMatch "\.php$">
    SetHandler "proxy:unix:/run/php/php8.3-myapp.sock|fcgi://localhost"
</FilesMatch>

Nginx:

Nginx
location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.3-myapp.sock;
    include fastcgi_params;
}

5. Связка Nginx + PHP-FPM

Nginx не имеет встроенного модуля для выполнения PHP, поэтому он всегда работает через FastCGI. PHP-FPM — стандартный и рекомендуемый способ интеграции.

5.1 Как это работает

Схема взаимодействия:

  1. Клиент отправляет запрос на Nginx (например, GET /index.php).
  2. Nginx получает запрос и смотрит на расширение файла.
  3. Если это .php, Nginx не обрабатывает его сам, а перенаправляет через FastCGI-протокол к PHP-FPM.
  4. PHP-FPM принимает запрос, запускает скрипт index.php, выполняет его (возможно, с подключением к БД, вычислениями).
  5. Результат выполнения (HTML, JSON) возвращается обратно в Nginx.
  6. Nginx отдаёт ответ клиенту.

5.2 Настройка Nginx + PHP-FPM

Шаг 1: Установка PHP-FPM и необходимых расширений

Bash
# Ubuntu/Debian (native или alt, как описано выше)
sudo apt install php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd php8.3-mbstring

Шаг 2: Запуск PHP-FPM

Bash
sudo systemctl start php8.3-fpm
sudo systemctl enable php8.3-fpm

Шаг 3: Настройка виртуального хоста в Nginx

Nginx
server {
    listen 80;
    server_name example.com;
    root /var/www/example/public;
    index index.php index.html index.htm;

    # Основной location для всех запросов
    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    # Обработка PHP-файлов через PHP-FPM
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    # Запрет доступа к скрытым файлам
    location ~ /\. {
        deny all;
    }

    # Кеширование статики (опционально)
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
        access_log off;
    }
}

Объяснение директив:

  • fastcgi_pass unix:/run/php/php8.3-fpm.sock — путь к Unix-сокету PHP-FPM (можно использовать TCP-сокет: 127.0.0.1:9000).
  • include fastcgi_params — подключает стандартные параметры FastCGI (обычно находится в /etc/nginx/fastcgi_params).
  • SCRIPT_FILENAME — передаёт полный путь к файлу скрипта.
  • PATH_INFO — используется для маршрутизации в некоторых фреймворках.

Шаг 4: Проверка конфигурации и перезагрузка

Bash
nginx -t
sudo systemctl reload nginx

5.3 Настройка пулов PHP-FPM для Nginx

В PHP-FPM можно создать несколько пулов (pools) для разных сайтов или приложений. Каждый пул имеет свои настройки процессов, пользователя, сокет и переменные окружения.

Пример создания пула для конкретного сайта:

Создайте файл /etc/php/8.3/fpm/pool.d/mysite.conf:

INI
[mysite]
user = mysite_user
group = mysite_group
listen = /run/php/php8.3-mysite.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

pm = dynamic
pm.max_children = 30
pm.start_servers = 5
pm.min_spare_servers = 3
pm.max_spare_servers = 15
pm.max_requests = 500

env[APP_ENV] = production
env[DB_HOST] = localhost

Затем в конфигурации Nginx укажите этот сокет:

Nginx
location ~ \.php$ {
    fastcgi_pass unix:/run/php/php8.3-mysite.sock;
    # ... остальные параметры
}

Преимущества отдельных пулов:

  • Изоляция сайтов друг от друга.
  • Разные ресурсы (память, CPU) под разные проекты.
  • Возможность перезапускать один пул без влияния на другие.
  • Удобное логирование ошибок для каждого пула.

5.4 Настройка медленных логов (slowlog)

Если скрипт выполняется слишком долго, это может указывать на проблему в коде или в базе данных. Медленный лог поможет её найти.

В конфигурации пула добавьте:

INI
slowlog = /var/log/php8.3-mysite-slow.log
request_slowlog_timeout = 5s

Теперь все скрипты, работающие более 5 секунд, будут записаны в этот файл с трассировкой стека.

5.5 Статусная страница PHP-FPM

PHP-FPM может предоставлять страницу с информацией о состоянии пулов.

В конфигурации пула добавьте:

INI
pm.status_path = /status

ВАЖНО! Этот путь должен быть уникальным на каждый пул (или использовать разные префиксы), иначе будет конфликт. И в Nginx обязательно ограничивать доступ!

В Nginx добавьте location для доступа к статусу (защитите его паролем или ограничьте по IP):

Nginx
location /status {
    allow 127.0.0.1;
    deny all;
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php8.3-mysite.sock;
}

Теперь по адресу http://example.com/status можно увидеть информацию о процессах, количестве запросов, загрузке и т.д.

6. Сравнение производительности: Apache vs Nginx + PHP-FPM

ПараметрApache + mod_phpApache + PHP-FPM (proxy_fcgi)Nginx + PHP-FPM
Обработка статикиСредняя (медленнее Nginx)СредняяВысокая
Обработка PHPВысокая (встроенный модуль)ВысокаяВысокая
Потребление памятиВысокое (каждый процесс Apache загружает PHP)Среднее (PHP в отдельных процессах)Низкое (Nginx лёгкий)
Управление процессамиApache управляет PHPPHP-FPM управляет процессамиPHP-FPM управляет процессами
ИзоляцияВсе сайты в одном процессе ApacheОтдельные пулы PHP-FPMОтдельные пулы PHP-FPM
Гибкость конфигурацииОграничена (всё в Apache)Высокая (пулы, настройки FPM)Высокая (пулы, настройки FPM)
Перезагрузка без потери соединенийДа (graceful)Да (reload)Да (reload)

Выводы:

  • Для проектов с высоким трафиком (особенно статика) Nginx + PHP-FPM предпочтительнее.
  • Apache + mod_php может быть проще в настройке, но менее производителен и безопасен.
  • Apache + proxy_fcgi — хороший компромисс, если вы хотите остаться на Apache, но получить преимущества PHP-FPM.
  • Рекомендуемая современная связка для большинства проектов — Nginx + PHP-FPM.

6.1 Как проверить производительность

Используйте инструменты нагрузочного тестирования, например ab (Apache Bench) или wrk:

Bash
# Тестирование 1000 запросов с параллельностью 10
ab -n 1000 -c 10 http://example.com/index.php

Сравнивайте время ответа, количество запросов в секунду и использование ресурсов (CPU, память) при разных конфигурациях.

7. Практические рекомендации

  1. Всегда используйте PHP-FPM, а не модуль PHP (mod_php) — это безопаснее и производительнее.
  2. Для Apache используйте mod_proxy_fcgi — это современный и рекомендуемый способ.
  3. Для Nginx используйте Unix-сокеты вместо TCP-сокетов — они быстрее (если PHP-FPM и Nginx на одной машине).
  4. Настраивайте отдельные пулы для каждого сайта, чтобы изолировать ресурсы и упростить диагностику.
  5. Включайте медленный лог (slowlog) — это поможет находить проблемные скрипты.
  6. Регулярно обновляйте PHP до последних стабильных версий (через альтернативные репозитории, если нужно).
  7. Ограничивайте pm.max_children в зависимости от доступной памяти на сервере.
  8. Используйте OPcache для ускорения выполнения PHP-скриптов (встроенный кеш байт-кода).
  9. Для высоконагруженных проектов настраивайте pm = static с фиксированным числом процессов (чтобы избежать накладных расходов на создание/уничтожение процессов).

Проверить текущую конфигурацию PHP‑FPM и прикинуть нагрузку можно с помощью нашего инструмента калькулятор пулов PHP‑FPM.

8. Заключение

Мы подробно разобрали все аспекты работы обработчиков PHP в современных веб-серверах. Вы узнали:

  • Отличие CGI от FastCGI и преимущества PHP-FPM.
  • Как настроить FastCGI в Apache через mod_fcgid и mod_proxy_fcgi.
  • В чём разница между native и alt версиями PHP и когда что выбирать.
  • Как работает связка Nginx + PHP-FPM с практическими примерами конфигурации.
  • Как создавать отдельные пулы и настраивать медленный лог.

Теперь вы готовы настраивать производительный, безопасный и гибкий стек для любых PHP-проектов — от небольших блогов до высоконагруженных веб-приложений.