Управление выполнением PHP-файлов на веб-сервере
Основные способы выполнения PHP-файлов
Веб-сервер обрабатывает PHP-код через один из механизмов интеграции. Выбор влияет на производительность, безопасность и гибкость администрирования. Ниже рассмотрены ключевые варианты с примерами и типичными сложностями.
Как добиться максимальной производительности при выполнении PHP?
Наиболее эффективным решением признано сочетание Nginx и PHP-FPM (FastCGI Process Manager). FPM управляет пулом процессов, поддерживает постоянное соединение и адаптируется под нагрузку.
Пример конфигурации Nginx для передачи PHP-запросов на сокет FPM:
server {
listen 80;
server_name example.com;
root /var/www/site;
location ~ \.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
выполнение файлов php (выполнение файлов php)
Пул FPM настраивается в файле pool.d/www.conf:
[www]
user = www-data
group = www-data
listen = /run/php/php8.2-fpm.sock
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
исполняемый php файл (исполняемый файл php)
Типичные проблемы:
- Ошибка 502 Bad Gateway – часто из-за того, что FPM не запущен или неверный путь к сокету. Проверка:
systemctl status php8.2-fpm. - Permission denied – несовпадение пользователя в пуле и владельца файлов. Решение: установить
user = nginxв пуле или изменить права на сокет. - Файлы не обрабатываются – отсутствует директива
fastcgi_param SCRIPT_FILENAME.
Как выполнить PHP-файлы через модуль Apache (mod_php)?
Цель: простота развертывания без дополнительных демонов. Модуль встраивается в Apache и выполняет PHP в том же процессе. Подходит для небольших проектов или при отказе от FPM.
Пример настройки в httpd.conf (или .htaccess):
LoadModule php_module modules/libphp.so
SetHandler application/x-httpd-php
DirectoryIndex index.php index.html
После изменений перезагрузите Apache: systemctl reload httpd.
Проблемы и ошибки:
- Большое потребление памяти – каждый процесс Apache содержит PHP-интерпретатор. Для высоких нагрузок рекомендуется FPM.
- Невозможность разделения пулов под разные сайты – все запросы выполняются с правами пользователя Apache.
- Ошибка 500 – версия модуля не соответствует установленному PHP.
Как выполнить PHP через обычный CGI?
Цель: выполнение PHP с правами отдельного пользователя (например, в shared-хостинге). Каждый запрос порождает новый процесс php-cgi.
Пример конфигурации Apache с ScriptAlias:
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
AllowOverride None
Options +ExecCGI
AddHandler cgi-script .php
CGI-скрипт PHP должен быть исполняемым: chmod +x /usr/lib/cgi-bin/php.
Проблемы:
- Низкая производительность из-за fork при каждом запросе.
- Сложность настройки переменных окружения – часто требуется задавать
PHP_FCGI_CHILDREN.
Как настроить выполнение PHP через FastCGI без FPM?
Цель: работа с серверами, не поддерживающими FPM (например, Lighttpd), или когда необходим прямой контроль над процессами
Пример запуска php-cgi в режиме FastCGI через spawn-fcgi:
spawn-fcgi -a 127.0.0.1 -p 9000 -u www-data -f /usr/bin/php-cgi -C 5
В конфигурации Nginx:
fastcgi_pass 127.0.0.1:9000;
Типичные ошибки:
- Не удаётся привязаться к порту – проверьте, не занят ли порт другим процессом.
- Процессы падают – настройте
PHP_FCGI_MAX_REQUESTSдля перезапуска.
Как использовать встроенный сервер PHP для быстрого тестирования?
Цель: разработка и отладка без установки полноценного веб-сервера. Встроенный сервер запускается одной командой и обслуживает один запрос за раз.
Пример запуска:
php -S 0.0.0.0:8080 -t /path/to/webroot
Результат: сервер слушает порт 8080, корень документа – указанная директория.
Ограничения и ошибки:
- Не предназначен для продакшена – только один поток, нет поддержки SSL, нет FastCGI.
- Если не указан файл маршрутизации (router), логика роутинга ложится на сам PHP.
Как выполнять PHP-файлы в изолированном Docker-контейнере?
Цель: полная изоляция окружения и упрощение развёртывания. Используют два контейнера: Nginx и PHP-FPM, связанные сетью.
Пример docker-compose.yml:
version: '3'
services:
web:
image: nginx:alpine
volumes:
- ./site:/usr/share/nginx/html
- ./nginx.conf:/etc/nginx/conf.d/default.conf
ports:
- "80:80"
php:
image: php:8.2-fpm
volumes:
- ./site:/var/www/html
Проблемы:
- Ошибка соединения – контейнеры должны быть в одной сети Docker.
- Права доступа – файлы в volume могут быть недоступны пользователю внутри контейнера.
Расширенные примеры настройки выполнения PHP
1. Множественные пулы PHP-FPM для разных веб-сайтов
Настройка отдельных пулов позволяет изолировать ресурсы и права. Создайте файл /etc/php/8.2/fpm/pool.d/site1.conf:
[site1]
user = site1
group = site1
listen = /run/php/site1.sock
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s
php_admin_value[open_basedir] = /home/site1/www
В Nginx для каждого location укажите свой сокет:
location ~ \.php$ {
fastcgi_pass unix:/run/php/site1.sock;
...
}
Результат: каждый сайт выполняется от своего пользователя и с ограниченным корнем файловой системы (open_basedir).
2. Оптимизация параметров pm (process manager) для FPM
Параметры pm, pm.max_children, pm.start_servers влияют на использование памяти. Для сайта с высокой нагрузкой:
pm = static
pm.max_children = 100
Проверка текущего количества процессов:
ps aux | grep php-fpm | grep -v grep | wc -l
Результат (пример): 54.
Если процессы превышают лимит, новые запросы будут отклоняться (502).
3. Использование chroot для изоляции PHP-процессов
FPM поддерживает chroot для отдельного пула. Пример конфигурации:
[chrooted]
chroot = /var/chroot/site
user = siteuser
group = siteuser
listen = /run/php/chrooted.sock
Внутри chroot должна быть полная копия необходимых библиотек и PHP. Ошибка – отсутствие /dev/null или /tmp.
4. Логирование медленных запросов в PHP-FPM
Для диагностики производительности:
[www]
request_slowlog_timeout = 2s
slowlog = /var/log/php-slow.log
Пример записи в логе:
[19-Jan-2025 12:34:56] [pool www] pid 1234 script_filename = /var/www/html/index.php [0x00007f...] file_get_contents() /var/www/html/index.php:5
5. Ограничение доступа через open_basedir и disable_functions
В пуле или php.ini укажите разрешённые директории и запрещённые функции:
php_admin_value[open_basedir] = /var/www/html:/tmp
php_admin_value[disable_functions] = exec,system,shell_exec
Проверка: PHP-скрипт с вызовом system('ls') завершится ошибкой.
6. Использование переменных окружения в FPM
Передайте переменные через конфигурацию пула:
[www]
env[MY_APP_ENV] = production
env[DB_PASSWORD] = secret123
В PHP доступ через getenv('MY_APP_ENV').