Интеграция веб-сервера Apache и языка PHP

Раздел: -> Веб-сервер

Основные способы интеграции Apache и PHP

Apache и PHP это классическая пара для динамических сайтов. Apache выступает в роли веб-сервера, а PHP как интерпретатор. Существует два основных подхода: модуль mod_php (встраиваемый интерпретатор) и связка с PHP-FPM через FastCGI. Каждый вариант имеет свои цели и особенности.

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

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

Пример установки в Ubuntu 22.04

sudo apt update
sudo apt install apache2 php libapache2-mod-php
sudo systemctl restart apache2

После установки Apache автоматически связывает файлы .php с PHP модулем. Для проверки создайте файл info.php в корневой папке (/var/www/html/info.php) с содержимым:

<?php phpinfo(); ?>

Откройте в браузере http://localhost/info.php. Если выводится информация о PHP, модуль работает.

Настройка обработки PHP файлов

По умолчанию Apache уже настроен. Но если требуется явно указать, используйте правила в конфигурации виртуального хоста:

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

Также можно задать индексный файл с PHP:

DirectoryIndex index.php index.html

Как настроить Apache для работы с PHP через FastCGI (PHP-FPM)?

Этот вариант подходит для серверов с несколькими сайтами или версиями PHP, так как PHP-FPM работает отдельным процессом и не зависит от модуля Apache. Требуется включить модули proxy и proxy_fcgi.

Пример установки и конфигурации

sudo apt install php-fpm apache2 libapache2-mod-php
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.3-fpm  # замените версию на вашу
sudo systemctl restart apache2

Теперь в виртуальном хосте используем директиву ProxyPassMatch:

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

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

    ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/var/www/example/$1
</VirtualHost>

Порт 9000 это стандартный порт PHP-FPM. Можно изменить в конфигурации пула /etc/php/8.3/fpm/pool.d/www.conf.

Типичная ошибка и её решение:

Если при обращении к PHP файлу отображается пустая страница или загрузка файла, проверьте, работает ли PHP-FPM: sudo systemctl status php8.3-fpm. Также убедитесь, что путь в ProxyPassMatch корректен и совпадает с реальной файловой системой.

Как переключать версии PHP в Apache без переустановки модуля?

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

Способ 1: смена модуля mod_php

sudo a2dismod php8.1
sudo a2enmod php8.3
sudo systemctl restart apache2

Важно: на сервере может быть установлена только одна версия libapache2-mod-php одновременно, иначе возникнет конфликт.

Способ 2: использование PHP-FPM для разных версий

sudo apt install php8.1-fpm php8.3-fpm
# Настроить каждый пул на свой порт или сокет
# В конфигурации виртуального хоста указать соответствующий fcgi://

Пример для двух сайтов на разных версиях:

<VirtualHost *:80>
    ServerName site1.local
    DocumentRoot /var/www/site1
    ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9001/var/www/site1/$1
</VirtualHost>

<VirtualHost *:80>
    ServerName site2.local
    DocumentRoot /var/www/site2
    ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9002/var/www/site2/$1
</VirtualHost>

Возможные проблемы:

При использовании одного порта для нескольких пулов возникает порт-конфликт. Используйте разные порты или сокеты Unix (unix:/run/php/php8.1-fpm.sock).

Как задать индивидуальные параметры PHP для каждого сайта?

Параметры PHP можно устанавливать через php_value и php_admin_value в контексте виртуального хоста или в файле .htaccess.

Пример для виртуального хоста

<VirtualHost *:80>
    ServerName myapp.local
    DocumentRoot /var/www/myapp
    <Directory /var/www/myapp>
        php_value upload_max_filesize 50M
        php_value post_max_size 100M
        php_admin_value open_basedir /var/www/myapp:/tmp
    </Directory>
</VirtualHost>

Пример для .htaccess

php_value upload_max_filesize 20M
php_value post_max_size 40M
php_value max_execution_time 120

Ошибки при использовании .htaccess:

Директива AllowOverride должна быть установлена в All или Options с включенным FileInfo. Если изменяемые параметры относятся к режиму PHP_INI_SYSTEM, их можно задать только через php_admin_value в конфигурации Apache.

Как ускорить выполнение PHP скриптов в Apache с помощью OPcache?

OPcache кэширует скомпилированные PHP скрипты в памяти, что значительно сокращает время выполнения. Включение по умолчанию присутствует в современных версиях PHP.

Проверка и настройка

# В файле /etc/php/8.3/apache2/php.ini или /etc/php/8.3/fpm/php.ini
opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
opcache.fast_shutdown=1

После изменений перезапустите Apache или PHP-FPM. Убедиться в работе можно через phpinfo() в секции Zend OPcache.

Проблема: кэш не обновляется при изменении файлов

Установите opcache.revalidate_freq равным 0 на стадии разработки, иначе изменения будут видны только через заданное время. Для продакшна оставьте 2-5 секунд.

Типичные ошибки и способы их устранения

1. 500 Internal Server Error при выполнении PHP скрипта - чаще всего синтаксическая ошибка. Включите отображение ошибок: в файле .htaccess добавьте php_flag display_errors on или в php.ini display_errors = On (только для разработки). Также проверьте логи Apache: tail -f /var/log/apache2/error.log.

2. Permission denied при открытии файлов PHP - убедитесь, что пользователь www-data (или тот, от которого работает Apache) имеет права на файлы и папки. Используйте chown -R www-data:www-data /var/www/html. Если включен SELinux, проверьте контексты или временно отключите: setenforce 0.

3. Пустая страница (White Screen of Death) - ошибка PHP, но вывод отключен. Включите логирование: log_errors = On и error_log = /var/log/php_errors.log.

4. Сессии не сохраняются - проблема с правами на папку сессий (обычно /tmp или /var/lib/php/sessions). Убедитесь, что Apache может писать туда: chmod 733 /var/lib/php/sessions (или другую директорию из session.save_path).

Расширенные примеры настройки и отладки

Ниже приведены подробные примеры кода, демонстрирующие различные сценарии работы Apache и PHP.

Пример 1: Виртуальный хост с PHP-FPM через Unix сокет

Использование сокета вместо TCP порта повышает безопасность и производительность.

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

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

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

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

После перезапуска Apache проверьте работу. Если PHP не обрабатывается, проверьте, что php8.3-fpm.sock существует и доступен для Apache (обычно права 666).

Пример 2: Индивидуальные настройки PHP через .htaccess с проверкой

Создайте файл .htaccess в корне сайта:

Пример
# Увеличить лимиты загрузки
php_value upload_max_filesize 64M
php_value post_max_size 128M
php_value max_execution_time 300

# Скрыть PHP версию
php_flag expose_php Off

# Отключить display_errors для продакшна
php_flag display_errors Off
php_flag log_errors On
php_value error_log /var/www/myapp/error.log

Убедитесь, что файл не имеет BOM и права доступа 644.

Пример 3: Оптимизация OPcache для высоконагруженного проекта

Рекомендуемые параметры для сайта с большим количеством файлов:

Пример
opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=20000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
opcache.validate_timestamps=0  # для продакшна, обновлять кэш вручную или через opcache_reset()

После изменения перезапустите PHP-FPM или Apache. Используйте opcache_get_status() для мониторинга.

Пример 4: Отладка через логи и отображение ошибок

Включение подробных логов для PHP в Apache:

Пример
# В /etc/php/8.3/apache2/php.ini
error_reporting = E_ALL
display_errors = On  # только для разработки
log_errors = On
error_log = /var/log/php_errors.log

Создайте скрипт для тестирования ошибок (test_error.php):

Пример
<?php
echo $undefined_var;
trigger_error('Тестовая ошибка пользователя', E_USER_WARNING);
include('несуществующий_файл.php');
?>

Результат в браузере (если display_errors включен) - отобразятся предупреждения. В логе /var/log/php_errors.log появятся записи.

[10-May-2025 12:00:00 UTC] PHP Notice:  Undefined variable: undefined_var in /var/www/html/test_error.php on line 2
[10-May-2025 12:00:00 UTC] PHP Warning:  Тестовая ошибка пользователя in /var/www/html/test_error.php on line 3
[10-May-2025 12:00:00 UTC] PHP Warning:  include(несуществующий_файл.php): Failed to open stream: No such file or directory in /var/www/html/test_error.php on line 4

Пример 5: ЧПУ (Clean URLs) с mod_rewrite и PHP

Классический пример для одностраничного приложения:

Пример
RewriteEngine On
RewriteBase /

# Если запрошен не существующий файл или директория, перенаправить на index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

В index.php обрабатывайте $_SERVER['REQUEST_URI']. Убедитесь, что модуль mod_rewrite включен: sudo a2enmod rewrite && sudo systemctl restart apache2.

Пример 6: Ограничение доступа к PHP файлам с помощью Directory

Запрет прямого обращения к служебным PHP файлам, например, в папке /inc:

Пример
<Directory /var/www/myapp/inc>
    <FilesMatch \.php$>
        Require all denied
    </FilesMatch>
</Directory>

Альтернатива: перенаправление на 403. Убедитесь, что порядок директив корректен (не перекрывается глобальным правилом).

Apache и PHP - comments

En
Apache php (php)