Основы php.ini
Что такое php.ini
php.ini -- главный конфигурационный файл PHP. Он читается один раз при старте интерпретатора (запуск PHP-FPM, Apache или CLI) и определяет поведение всего движка.
Порядок поиска конфигурации
PHP ищет php.ini в определённой последовательности:
- Переменная окружения
PHPRC(если задана) - Путь, специфичный для SAPI (например,
/etc/php/8.4/fpm/) - Путь, указанный при компиляции (
--with-config-file-path) - Текущая рабочая директория (только CLI)
- Директория сервера (для SAPI-модулей)
- Системные директории (
/etc/на Linux)
<?php
// Find where PHP looks for configuration
echo php_ini_loaded_file();
// Example: /etc/php/8.4/fpm/php.ini
echo php_ini_scanned_files();
// /etc/php/8.4/fpm/conf.d/10-opcache.ini,
// /etc/php/8.4/fpm/conf.d/20-curl.ini, ...
Стандартные пути для разных SAPI
Linux (FPM): /etc/php/8.4/fpm/php.ini
Linux (CLI): /etc/php/8.4/cli/php.ini
macOS (brew): /opt/homebrew/etc/php/8.4/php.ini
Docker: /usr/local/etc/php/php.ini
Windows: C:\php\php.ini
Критически важно: CLI и FPM используют разные файлы php.ini. Изменение настроек в одном не влияет на другой. Это частая причина "у меня в терминале работает, а на сайте нет".
php.ini-development vs php.ini-production
PHP поставляется с двумя шаблонами конфигурации. Ни один из них не является активным по умолчанию -- нужно скопировать выбранный в php.ini.
| Директива | development | production | Почему |
|---|---|---|---|
display_errors |
On | Off | Безопасность: не показывать ошибки пользователю |
display_startup_errors |
On | Off | Ошибки при старте PHP |
error_reporting |
E_ALL | E_ALL | Логировать все уровни |
log_errors |
On | On | Всегда писать логи |
error_log |
(пусто) | (пусто) | Настроить путь вручную! |
opcache.enable |
0 | 1 | Кеширование для производительности |
zend.exception_ignore_args |
Off | On | Не хранить аргументы в stack trace |
zend.exception_string_param_max_len |
15 | 0 | Не показывать параметры |
mysqlnd.collect_memory_statistics |
On | Off | Сбор статистики замедляет |
# Setting up configuration from template
cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
# In Docker
COPY --from=build /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
phpinfo() -- полная справка
<?php
// Full information (NEVER leave on production!)
phpinfo();
// Specific sections using constants
phpinfo(INFO_GENERAL); // PHP version, build date, SAPI
phpinfo(INFO_CONFIGURATION); // php.ini directives and values
phpinfo(INFO_MODULES); // Loaded extensions and settings
phpinfo(INFO_ENVIRONMENT); // Environment variables
phpinfo(INFO_VARIABLES); // $_SERVER, $_ENV, $_GET, etc.
// Section flags can be combined with bitwise OR
phpinfo(INFO_GENERAL | INFO_CONFIGURATION);
CLI-альтернативы
# Quick directive lookup
php -i | grep memory_limit
# Get specific value
php -r "echo ini_get('memory_limit');"
# List all loaded ini files
php --ini
# Show compiled-in configuration path
php -i | grep "Configuration File"
Безопасность:
phpinfo()раскрывает версии ПО, пути файловой системы, переменные окружения и расширения. На production это прямой вектор атаки.
ini_get() и ini_set()
Чтение значений
<?php
// ini_get() always returns string (or false if directive doesn't exist)
$memLimit = ini_get('memory_limit'); // "128M"
$maxExec = ini_get('max_execution_time'); // "30"
$display = ini_get('display_errors'); // "0" or "1"
// WARNING: boolean directives return "0", "1", "" or "Off", "On"
var_dump(ini_get('display_errors')); // string("0")
// Correct boolean check
$isEnabled = filter_var(
ini_get('display_errors'),
FILTER_VALIDATE_BOOLEAN
);
// ini_get_all() -- all directives with access levels
$all = ini_get_all();
// ['directive' => ['global_value' => '...', 'local_value' => '...', 'access' => 7]]
// Directives for specific extension
$opcache = ini_get_all('opcache');
Изменение значений
<?php
// ini_set() changes value for CURRENT SCRIPT only
$oldValue = ini_set('memory_limit', '256M');
echo "Was: $oldValue, Now: " . ini_get('memory_limit');
// Restore original value from php.ini
ini_restore('memory_limit');
echo ini_get('memory_limit'); // Back to php.ini value
// ini_set() returns false on failure (directive doesn't exist or wrong level)
$result = ini_set('upload_max_filesize', '100M'); // false! (PHP_INI_PERDIR)
Уровни конфигурации (INI Access Levels)
Каждая директива PHP имеет уровень доступа, определяющий, где её можно изменить.
| Уровень | Значение | Где можно изменить |
|---|---|---|
PHP_INI_USER |
1 | ini_set(), .user.ini |
PHP_INI_PERDIR |
2 | .user.ini, .htaccess, httpd.conf |
PHP_INI_SYSTEM |
4 | Только php.ini, httpd.conf |
PHP_INI_ALL |
7 | Все способы (1+2+4) |
<?php
// Check access level of any directive
$info = ini_get_all();
echo $info['memory_limit']['access']; // 7 (PHP_INI_ALL)
echo $info['upload_max_filesize']['access']; // 6 (PERDIR + SYSTEM)
echo $info['max_file_uploads']['access']; // 4 (PHP_INI_SYSTEM)
echo $info['error_reporting']['access']; // 7 (PHP_INI_ALL)
Практические следствия
<?php
// PHP_INI_ALL -- can change anywhere
ini_set('memory_limit', '512M'); // Works
ini_set('error_reporting', (string) E_ALL); // Works
ini_set('max_execution_time', '60'); // Works
// PHP_INI_PERDIR -- only php.ini, .user.ini, httpd.conf
ini_set('upload_max_filesize', '100M'); // SILENTLY IGNORED!
ini_set('session.save_handler', 'redis'); // SILENTLY IGNORED!
// PHP_INI_SYSTEM -- only php.ini and httpd.conf
ini_set('disable_functions', 'exec'); // SILENTLY IGNORED!
ini_set('open_basedir', '/var/www'); // SILENTLY IGNORED!
Для экзамена:
ini_set()для директивы с неподходящим уровнем не вызывает ошибку -- вызов просто игнорируется и возвращаетfalse.
.user.ini -- пользовательская конфигурация
.user.ini -- аналог .htaccess для PHP-FPM (и FastCGI). Размещается в любой директории проекта и влияет на файлы в ней и поддиректориях.
; /var/www/project/.user.ini
; PHP_INI_ALL and PHP_INI_PERDIR directives work here
memory_limit = 256M
upload_max_filesize = 50M
post_max_size = 55M
max_execution_time = 60
; PHP_INI_SYSTEM directives DO NOT work here!
; disable_functions = exec ; This line has no effect
; max_file_uploads = 100 ; This line has no effect
Кеширование .user.ini
; Controlled by these php.ini directives:
user_ini.filename = ".user.ini" ; File name (can be changed)
user_ini.cache_ttl = 300 ; Cache TTL in seconds (default 5 min)
Важно: После изменения
.user.iniнужно подождать доuser_ini.cache_ttlсекунд или перезапустить PHP-FPM..user.iniработает только с PHP-FPM и FastCGI. С Apache mod_php используется.htaccessсphp_value/php_flag.
Приоритет применения настроек
php.ini (самый низкий приоритет)
|
conf.d/*.ini (дополнительные файлы, в алфавитном порядке)
|
.user.ini (пользовательская конфигурация)
|
ini_set() (самый высокий, только PHP_INI_ALL/PHP_INI_USER)
<?php
// php.ini: memory_limit = 128M
// .user.ini: memory_limit = 256M
// Script:
ini_set('memory_limit', '512M');
echo ini_get('memory_limit'); // "512M" -- ini_set() wins
ini_restore('memory_limit');
echo ini_get('memory_limit'); // "256M" -- .user.ini value (FPM)
// Check both values
$info = ini_get_all(null, true)['memory_limit'];
echo $info['global_value']; // "128M" (from php.ini)
echo $info['local_value']; // "512M" (current effective)
Формат значений в php.ini
; Strings
error_log = /var/log/php/error.log
; Numbers
max_execution_time = 30
; Sizes with suffixes: K (kilobytes), M (megabytes), G (gigabytes)
memory_limit = 128M
post_max_size = 64M
; Boolean values (all equivalent)
display_errors = On ; On, Off, 1, 0, true, false, yes, no
; Lists (comma-separated)
disable_functions = exec,shell_exec,system,passthru,proc_open
; Empty value (disable/unset)
error_log =
; Comments
; This is a comment (semicolons only)
Частая ошибка:
memory_limit = 128(без суффикса) означает 128 байт, а не 128 мегабайт!
Конфигурация через переменные окружения (Docker)
; In Docker, override directives via environment variables
; PHP_INI_SCAN_DIR controls additional .ini directories
; /usr/local/etc/php/conf.d/docker.ini
; Use envsubst or sed in entrypoint:
memory_limit = ${PHP_MEMORY_LIMIT:-128M}
# Docker entrypoint approach
envsubst < /usr/local/etc/php/conf.d/docker.ini.template \
> /usr/local/etc/php/conf.d/docker.ini
# Or override with -d flag
php -d memory_limit=256M script.php