Подключение PHP к Apache с помощью mod_php
Настройка mod_php в Apache: основные подходы и варианты
Как подключить модуль mod_php к Apache, чтобы сервер обрабатывал PHP-скрипты?
Основной способ – загрузить модуль и назначить обработчик для файлов с расширением .php.
LoadModule php_module modules/libphp.so
AddHandler php-script .php
Эти директивы обычно размещают в основном конфигурационном файле httpd.conf или в отдельном файле в папке conf.d. После перезапуска Apache любой запрос к файлу .php будет обрабатываться модулем PHP.
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
Такой подход работает во всех версиях Apache 2.x.
Типичная проблема:
Если модуль не загружается, Apache выдаёт ошибку "Cannot load modules/libphp.so into server: No such file or directory". Решение: проверить путь к модулю, наличие файла, установить libphp*.so через пакетный менеджер (например, apt install libapache2-mod-php).
Также возможна ошибка "Handler for .php not found" – в этом случае нужно убедиться, что директива AddHandler указана после LoadModule.
Как настроить обработку PHP только в определённой директории, не затрагивая весь сервер?
Использовать контейнер <Directory> или <Location>.
<Directory /var/www/mysite>
SetHandler application/x-httpd-php
</Directory>
Цель: изолировать обработку PHP для конкретного сайта или папки, не нагружая весь сервер.
Ошибка: если не указать Options +ExecCGI для этой директории, может появиться 403 Forbidden.
Как заставить PHP обрабатывать расширения, отличные от .php (например, .phtml, .php5)?
Добавить несколько директив AddHandler или FilesMatch.
AddHandler php-script .php .phtml .php5
Или через FilesMatch:
<FilesMatch "\.(php|phtml|php5)$">
SetHandler application/x-httpd-php
</FilesMatch>
Важно: такие расширения могут снижать безопасность, если позволяют загрузку файлов с двойным расширением.
Проблема: если файл .php5 не обрабатывается, проверить, что модуль установлен для версии PHP, поддерживающей .php5, и что расширение не переопределено в .htaccess.
Как задать собственный php.ini для каждого виртуального хоста?
Использовать директиву PHPINIDir.
<VirtualHost *:80>
DocumentRoot /var/www/site1
PHPINIDir /etc/php/site1/
</VirtualHost>
В указанной директории должен находиться файл php.ini (или .user.ini). Цель: разделить настройки PHP для разных сайтов (разные memory_limit, upload_max_filesize и т.д.).
Ошибка: если директива не срабатывает, возможно, используется не mpm-prefork, а mpm-worker, с которым mod_php несовместим. Переключиться на prefork или использовать PHP-FPM.
Как использовать mod_php совместно с другими обработчиками (например, mod_fastcgi для других версий PHP)?
Можно сосуществовать, используя разные расширения или директории. Например, для файлов с расширением .php7 настроить обработчик PHP 7 через mod_php, а для .php8 через mod_fastcgi.
<FilesMatch \.php7$>
SetHandler application/x-httpd-php7
</FilesMatch>
AddHandler php7-script .php7
Однако обычно лучше выбрать один механизм.
Проблема: конфликт модулей при разных версиях – Apache может загрузить только один mod_php за раз. Решение: использовать разные MPM (например, prefork для mod_php, event для FPM).
Расширенные примеры конфигураций и отладка
Пример 1: Настройка лимитов PHP через httpd.conf
Прямое указание параметров php.ini в конфигурации Apache с помощью директивы php_value.
<Directory /var/www/site>
php_value upload_max_filesize 64M
php_value post_max_size 70M
php_value memory_limit 128M
php_value max_execution_time 300
</Directory>
Результат: PHP-скрипты в этой директории получат увеличенные лимиты. Проверяется через phpinfo(): значения появятся в разделах "Local Value" и "Master Value".
PHP Info: upload_max_filesize = 64M, memory_limit = 128M
Важно: php_value можно использовать только в контексте Directory, VirtualHost, .htaccess. В секции <IfModule> директива не сработает.
Ошибка: если указать недопустимое имя настройки, Apache не запустится с сообщением "Invalid command 'php_value'". Проверить, загружен ли mod_php и есть ли права на изменение настроек.
Пример 2: Использование PHPINIDir для разных виртуальных хостов с разными версиями php.ini
<VirtualHost *:80>
DocumentRoot /var/www/site2
ServerName site2.example.com
PHPINIDir /etc/php/site2
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
</VirtualHost>
В каталоге /etc/php/site2 создаётся файл php.ini с произвольными настройками. Результат: для site2.example.com работают отдельные лимиты и настройки.
Пример 3: Отладка загрузки модуля и обработчика
Проверка, какие модули загружены:
httpd -M | grep php
Результат:
php_module (shared)
Если модуль не отображается, проверить синтаксис конфигурации:
httpd -t
Результат:
Syntax OK
При ошибке синтаксиса Apache покажет строку с проблемой.
Пример 4: Настройка нескольких версий PHP через mod_php (сборка из исходников)
Если скомпилировать PHP как модуль с флагом --with-apxs2, получится libphp7.so. Для версии 8 – libphp8.so. В конфигурации Apache подключаются оба, но одновременно активен только один из-за конфликта имён. Решение: переименовать модули и обработчики:
LoadModule php7_module modules/libphp7.so
LoadModule php8_module modules/libphp8.so
AddHandler php7-script .php7
AddHandler php8-script .php8
Затем для каждого расширения указать свой обработчик. Так можно параллельно обслуживать файлы с разными расширениями старыми и новыми версиями PHP.
Пример 5: Использование .htaccess для изменения настроек без доступа к основному конфигу
php_value upload_max_filesize 32M
php_value post_max_size 40M
php_value memory_limit 64M
php_flag display_errors on
Размещается в корне сайта. Результат: настройки действуют только для этой директории. Важно, чтобы в httpd.conf было разрешено переопределение (AllowOverride All).
Проблема: если AllowOverride не установлен, Apache проигнорирует .htaccess.