Настройка интерпретатора PHP: директивы и методы управления
Эффективные способы конфигурации PHP
Основной метод: редактирование php.ini
Как получить доступ к основному конфигурационному файлу PHP?
PHP использует файл php.ini для глобальных настроек. Его расположение зависит от системы. Команда php --ini показывает путь. После редактирования необходимо перезапустить веб-сервер или PHP-FPM.
Примеры директив:
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 68M
max_execution_time = 60
display_errors = On
error_reporting = E_ALL
Пояснения: memory_limit задает максимальный объем памяти для скрипта; upload_max_filesize ограничивает размер загружаемых файлов; post_max_size должен быть чуть больше upload_max_filesize для учета метаданных; max_execution_time ограничивает время работы скрипта; display_errors включает вывод ошибок на экран (рекомендуется отключать на production).
Типичные ошибки: неверный синтаксис (пробелы вокруг = не критичны), указание значения с пробелами (допустимо), использование недопустимых единиц (например, M вместо MB). Также необходимо проверить, что файл php.ini читается: после изменения выполнить phpinfo() и проверить раздел 'Loaded Configuration File'. Забыли перезапустить сервер - изменения не вступят в силу.
Вариант через .htaccess (для Apache с mod_php)
Как изменить настройки PHP без доступа к php.ini?
Если используется Apache с модулем mod_php, можно применить директивы в файле .htaccess. Для этого необходимо включить опцию AllowOverride All в конфигурации виртуального хоста.
<IfModule mod_php.c>
php_value memory_limit 128M
php_value upload_max_filesize 32M
php_flag display_errors on
</IfModule>
Директивы применяются ко всем скриптам в директории с .htaccess и подпапках. Важно: некоторые директивы (например, с префиксом php_admin_value) работают только в конфигурации сервера, не в .htaccess.
Проблемы: если AllowOverride не разрешен, файл .htaccess игнорируется. Ошибки могут проявляться как 500 Internal Server Error. Для отладки следует проверить логи Apache. Также не все директивы PHP допустимы в .htaccess; можно использовать только те, что относятся к PHP_INI_ALL или PHP_INI_PERDIR.
Цель: удобно для хостингов, где нет доступа к глобальной конфигурации, или для быстрого тестирования.
Вариант через .user.ini (для CGI/FastCGI)
Как применить настройки только для конкретной директории?
При использовании PHP-FPM или CGI поддерживается файл .user.ini. Он работает аналогично php.ini, но применяется к текущей директории.
; файл .user.ini в корне проекта
memory_limit = 128M
upload_max_filesize = 32M
display_errors = Off
Этот способ удобен для хостингов, где нет доступа к глобальному php.ini. Настройки каскадно наследуются от родительских директорий. Для применения изменений не требуется перезагрузка сервера, так как проверка происходит при каждом запросе.
Проблемы: не все SAPI поддерживают .user.ini; обычно это CGI и FastCGI (включая FPM). Настройки могут быть переопределены в более глубоком уровне. Также возможны ошибки синтаксиса, как в обычном php.ini. Файлы .user.ini не защищены от скачивания, если не настроен веб-сервер.
Случаи использования: изоляция настроек для разных проектов на общем сервере.
Вариант через функцию ini_set() в коде
Как временно изменить директиву PHP внутри скрипта?
Для изменения параметров во время выполнения используется функция ini_set('directive', value). Изменение действует только на текущий скрипт и не влияет на другие запросы.
<?php
ini_set('memory_limit', '256M');
ini_set('max_execution_time', 120);
echo 'Memory limit: ' . ini_get('memory_limit');
?>
Этот метод полезен для скриптов, которым требуется больше ресурсов, чем задано глобально. Необходимо помнить, что не все директивы можно изменить: те, что помечены как PHP_INI_SYSTEM, доступны только в php.ini.
Типичные ошибки: попытка изменить директиву, которая не позволяет это делать (например, disable_functions). Функция возвращает false при неудаче, что можно проверить. Также изменение не влияет на уже запущенные скрипты. Нельзя изменить параметры сессии после её старта.
Цель: гибкая адаптация под конкретный скрипт или задачу.
Вариант через конфигурацию PHP-FPM pool
Как настроить параметры PHP для разных сайтов при использовании PHP-FPM?
В PHP-FPM можно задать директивы для каждого пула отдельно. Файлы пулов находятся в /etc/php/*/fpm/pool.d/. Директивы могут быть установлены с помощью php_value, php_admin_value и php_flag.
[www]
user = www
group = www
listen = /run/php/php8.2-fpm.sock
pm.max_children = 10
pm.start_servers = 3
php_admin_value[memory_limit] = 128M
php_admin_value[upload_max_filesize] = 64M
php_admin_flag[display_errors] = off
После изменений необходимо перезагрузить пул: systemctl reload php8.2-fpm или kill -USR2 pid. Этот подход позволяет гибко управлять ресурсами для разных сайтов.
Проблемы: неправильный синтаксис в конфигурации пула приводит к тому, что пул не запускается. Логи FPM находятся в syslog или в файле error_log. Также необходимо следить за правами: пользователь в директиве user должен существовать и иметь доступ к файлам. Перегрузка пула может вызвать временную недоступность.
Случаи использования: разделение ресурсов между несколькими веб-приложениями на одном сервере.
Расширенные примеры конфигурации PHP
Полный пример php.ini для production среды
Приведенная ниже конфигурация ориентирована на безопасность и производительность. Она включает отключение отображения ошибок, установку оптимальных лимитов и запрет опасных функций.
; Основные настройки
memory_limit = 256M
max_execution_time = 30
max_input_time = 60
post_max_size = 64M
upload_max_filesize = 64M
; Обработка ошибок (скрываем на prod)
display_errors = Off
log_errors = On
error_log = /var/log/php_errors.log
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
; Безопасность
disable_functions = exec, system, passthru, shell_exec, popen, proc_open
allow_url_fopen = Off
allow_url_include = Off
open_basedir = /var/www/html:/tmp
; Сессии
session.save_path = /var/lib/php/sessions
session.use_strict_mode = 1
; Оптимизация
realpath_cache_size = 4096k
realpath_cache_ttl = 600
После применения необходимо перезагрузить веб-сервер. Результат можно проверить через phpinfo().
Loaded Configuration File: /etc/php/8.2/cli/php.ini memory_limit = 256M display_errors = Off disable_functions = exec, system, ...
Настройка для разработки с отображением ошибок и Xdebug
Во время разработки полезно видеть все ошибки и предупреждения. Включение Xdebug помогает отлаживать код.
; php.ini для разработки
display_errors = On
display_startup_errors = On
error_reporting = E_ALL
; Xdebug
zend_extension = xdebug.so
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.client_host = 127.0.0.1
xdebug.client_port = 9003
; Увеличиваем время и память для отладки
max_execution_time = 0
memory_limit = 512M
Результат: ошибки выводятся на экран, Xdebug перехватывает точки останова.
(пример вывода ошибки: Notice: Undefined variable: x in ... on line 10)
Использование .htaccess с условиями по IP
Часто требуется включить вывод ошибок только для определенного IP-адреса (например, разработчика).
# .htaccess
SetEnvIf Remote_Addr "192.168.1.100" dev_ip
php_flag display_errors On
</IfModule>
<IfModule mod_setenvif.c>
SetEnvIfNoCase Remote_Addr "^10\.0\.0\." dev_network
php_admin_value error_reporting E_ALL & ~E_NOTICE
</IfModule>
Для данного примера нужно проверить, что модули mod_setenvif и mod_php загружены.
Пример .user.ini с каскадным переопределением
В корне проекта разрешим загрузку файлов до 32M, а в поддиректории /admin увеличим лимит до 128M.
; /var/www/project/.user.ini
upload_max_filesize = 32M
post_max_size = 36M
; /var/www/project/admin/.user.ini
upload_max_filesize = 128M
post_max_size = 130M
При запросе к /admin/index.php применится лимит 128M.
Настройка PHP-FPM пула для высоконагруженного сайта
Для сайта с большим трафиком важно правильно рассчитать количество процессов. Пример для 8-ядерного сервера с 32 ГБ RAM:
[highload]
user = www
group = www
listen = /run/php/php8.2-fpm-highload.sock
pm = dynamic
pm.max_children = 200
pm.start_servers = 50
pm.min_spare_servers = 20
pm.max_spare_servers = 80
pm.max_requests = 500
request_terminate_timeout = 90
php_admin_value[memory_limit] = 128M
php_admin_value[upload_max_filesize] = 10M
После изменений: systemctl reload php8.2-fpm. Рекомендуется мониторить использование памяти.
Комбинирование методов: php.ini + ini_set для модуля
Глобально в php.ini задан memory_limit = 128M, но для отчета, генерирующего большой PDF, используется ini_set:
<?php
// report.php
ini_set('memory_limit', '512M');
// генерация отчета
?>
Результат: отчет сгенерируется, не затрагивая другие скрипты.