Конфигурация Apache 2.4 и PHP: практическое руководство

Раздел: Администрирование серверов -> Конфигурация веб-сервера

Настройка Apache 2.4 для работы с PHP

Основное решение: модуль mod_php (исполнение PHP внутри Apache)

Этот способ подходит, если используется MPM prefork и требуется максимальная производительность для статических PHP-скриптов. PHP-интерпретатор встраивается непосредственно в процесс Apache, что даёт наименьшую задержку.

Пошаговая установка (на примере PHP 8.2, Debian/Ubuntu)

sudo apt update
sudo apt install apache2 php8.2 libapache2-mod-php8.2
sudo a2enmod php8.2
sudo systemctl restart apache2

После установки модуль mod_php автоматически подключает обработчик для файлов .php. Убедиться в этом можно командой:

sudo apache2ctl -M | grep php

Вывод должен содержать строку php8_module (или php7_module).

Типичные ошибки и их решение

Проблема: Файлы PHP не обрабатываются, браузер выводит исходный код.

Причина: Отсутствует директива AddType application/x-httpd-php .php или модуль не включён.

Решение: Проверьте конфигурацию в файле /etc/apache2/mods-enabled/php8.2.conf. Если его нет – выполните sudo a2enmod php8.2. Вручную можно добавить в virtual host:

<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

Проблема: Конфликт с PHP-FPM, когда одновременно активированы mod_php и mod_proxy_fcgi.

Решение: Отключите mod_php, если используете FPM: sudo a2dismod php8.2.

Вариант: PHP-FPM через mod_proxy_fcgi (для event/worker MPM)

Как настроить Apache для работы с PHP-FPM?

Этот вариант позволяет отделить процесс PHP от Apache, используя быстрый CGI-прокси. Рекомендуется для сайтов с высокой нагрузкой и при использовании MPM event или worker.

Установка и настройка

sudo apt install php8.2-fpm
sudo a2enmod proxy_fcgi setenvif
sudo systemctl restart apache2

Далее нужно указать Apache обрабатывать PHP через сокет PHP-FPM. Внутри virtual host добавить:

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

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

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Проверить синтаксис конфигурации: sudo apache2ctl configtest.

Проблема: Ошибка 502 Bad Gateway.

Причина: PHP-FPM не запущен, или не совпадает путь к сокету.

Решение: Проверьте статус sudo systemctl status php8.2-fpm. Убедитесь, что сокет существует (ls -la /run/php/). Если используется TCP-порт (например, 127.0.0.1:9000), замените unix-сокет на fcgi://127.0.0.1:9000.

Проблема: PHP-скрипты выполняются, но медленно.

Решение: Увеличьте количество процессов PHP-FPM в его конфигурации (/etc/php/8.2/fpm/pool.d/www.conf): pm.max_children = 50. Или используйте директиву ProxySet для настройки таймаутов в Apache.

Вариант: CGI (mod_cgi) – устаревший, но совместимый

Когда имеет смысл использовать CGI для PHP?

Этот способ применяется очень редко, в основном для изоляции PHP-скриптов в средах с повышенными требованиями безопасности, либо для совместимости с очень старыми версиями PHP. Каждый запрос запускает отдельный процесс интерпретатора.

Настройка

sudo a2enmod cgi
sudo systemctl restart apache2

# В virtual host:
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
    AllowOverride None
    Options +ExecCGI
    AddHandler cgi-script .php
    Require all granted
</Directory>

Скрипты помещаются в каталог /usr/lib/cgi-bin/ и должны иметь права на выполнение.

Проблема: Ошибка 403 Forbidden при попытке доступа к cgi-скрипту.

Причина: Неправильные права или отсутствие директивы Options +ExecCGI.

Решение: Установите права 755 на скрипт и проверьте, что Apache может читать каталог. Добавьте Require all granted.

Проблема: Высокая нагрузка на сервер при большом количестве запросов.

Причина: CGI запускает новый процесс на каждый запрос.

Решение: Используйте PHP-FPM или mod_php вместо CGI.

Расширенные примеры конфигурации и отладки

1. Полный Virtual Host с поддержкой PHP (mod_php и PHP-FPM в одном домене)

Пример
<VirtualHost *:8080>
    ServerName app.local
    DocumentRoot /var/www/app

    # Для статики используем кеширование
    <LocationMatch "\.(jpg|png|css|js)$">
        Header set Cache-Control "max-age=86400, public"
    </LocationMatch>

    # PHP через mod_php (если нужен быстрый путь)
    <FilesMatch "\.php$">
        SetHandler application/x-httpd-php
    </FilesMatch>

    # Альтернативный путь через PHP-FPM для отдельных скриптов
    <Location /admin/>
        SetHandler "proxy:unix:/var/run/php/php8.2-fpm.sock|fcgi://localhost"
    </Location>

    ErrorLog ${APACHE_LOG_DIR}/app-error.log
    CustomLog ${APACHE_LOG_DIR}/app-access.log combined
</VirtualHost>
# Результат: запросы к /index.php обрабатываются mod_php, к /admin/script.php – PHP-FPM.
# Лог показывает два разных обработчика.

2. Проверка конфигурации с помощью phpinfo()

Пример
# Создайте файл info.php в корне DocumentRoot:
<?php phpinfo(); ?>

# Затем откройте в браузере http://example.com/info.php
# Вы увидите секцию 'Server API' – она показывает, какой обработчик используется (Apache 2.0 Handler – для mod_php, FPM/FastCGI – для PHP-FPM).

3. Отладка проблем с PHP-FPM через переменные окружения

Пример
# Включите логирование ошибок PHP-FPM:
sudo nano /etc/php/8.2/fpm/pool.d/www.conf
# Раскомментируйте или добавьте:
catch_workers_output = yes
php_admin_value[error_log] = /var/log/php-fpm-error.log

# Используйте SetEnvIf в Apache для проброса переменных:
SetEnvIf Request_URI ^/api no-gzip
<LocationMatch "/api/.*\.php$">
    SetHandler "proxy:fcgi://127.0.0.1:9000"
    Header set X-Debug-Proxy "PHP-FPM"
</LocationMatch>
# Результат: в заголовках ответа появляется X-Debug-Proxy: PHP-FPM.
# Лог PHP-FPM содержит детальные сообщения об ошибках конкретного скрипта.

4. Настройка таймаутов и лимитов через ProxySet

Пример
<VirtualHost *:80>
    ServerName slow.example.com
    DocumentRoot /var/www/slow

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

    <Proxy fcgi://localhost enablereuse=On max=10 timeout=300>
        # Увеличенный таймаут для долгих скриптов
        ProxySet timeout=600
    </Proxy>

    TimeOut 600
</VirtualHost>
# Результат: Apache ждёт ответа от PHP-FPM до 10 минут, прежде чем вернуть ошибку 504 Gateway Timeout.
# Значение enablereuse=On позволяет переиспользовать соединения.

5. Использование .htaccess для переключения обработчика PHP

Пример
# В каталоге /var/www/example/subdir/ создаём .htaccess:
RewriteEngine On
RewriteRule ^test\.php$ - [E=HANDLER:proxy:fcgi://127.0.0.1:9000]

# Или задаём обработчик через SetHandlerIf:
<If "%{REQUEST_URI} =~ /legacy/">
    SetHandler cgi-script
</If>
# Результат: для всех файлов в подкаталоге test.php обрабатывается через PHP-FPM, остальные – через mod_php.
# Удобно при поэтапном переходе с mod_php на FPM.

Apache 2.4 и PHP - comments

En
Apache 2.4 php (php)