Управление объемом выделяемой памяти для PHP: варианты и рекомендации
Основные аспекты настройки памяти PHP
Параметр memory_limit определяет максимальный объем памяти, который может использовать один PHP-скрипт. Неправильная настройка приводит к фатальным ошибкам Allowed memory size exhausted или к неэффективному расходованию ресурсов сервера. Далее рассматриваются различные способы изменения этого параметра.
Как задать ограничение памяти для всех скриптов на сервере наиболее надёжным способом?
Наиболее эффективное решение - редактирование главного конфигурационного файла php.ini. Этот способ действует на все виртуальные хосты и интерпретаторы (CLI, FPM, модуль Apache).
; Откройте php.ini (обычно /etc/php/8.x/cli/php.ini или /etc/php/8.x/fpm/php.ini)
; Найдите директиву memory_limit и измените её значение
memory_limit = 256MПосле изменения необходимо перезапустить веб-сервер или PHP-FPM:
sudo systemctl restart php8.3-fpm # для FPM
sudo systemctl restart apache2 # для mod_phpПроблема:
После изменения значения память не увеличивается.Решение:
Проверьте, какой именно php.ini загружается (команда php --ini). Иногда используется несколько копий файла.Как изменить лимит памяти для одного скрипта без прав на редактирование php.ini?
Использование функции ini_set внутри кода. Эффект распространяется только на текущий скрипт и его дочерние вызовы.
<?php
// Устанавливаем лимит в 512 мегабайт
ini_set('memory_limit', '512M');
// Код, которому требуется больше памяти
?>Проблема:
Функция может не сработать, если значение превышает максимальное ограничение, заданное в php.ini (memory_limit для директории).Решение:
В php.ini задайте значение -1 (безлимит) или установите высокий верхний предел.Целесообразно для ресурсоёмких операций (генерация отчётов, обработка изображений).
Как настроить память для отдельной папки через .user.ini (PHP-FPM)?
Создайте файл .user.ini в корне проекта - он будет применён к скриптам в этой и вложенных директориях (работает только в FPM/CGI).
; .user.ini в корне сайта
memory_limit = 128M
upload_max_filesize = 32MПроблема:
Изменения не применяются из-за кеширования.Решение:
PHP перечитывает .user.ini при каждом запросе, однако может потребоваться перезапуск FPM, если кеш OPcache блокирует.Идеально для shared-хостинга, где нет доступа к основным настройкам.
Каким образом установить лимит через .htaccess (только для Apache с модулем mod_php или CGI)?
Добавить директиву php_value.
# .htaccess
php_value memory_limit 256M
php_value upload_max_filesize 64MПроблема:
На некоторых серверах директива запрещена (AllowOverride None).Решение:
Используйте .user.ini или ini_set.Подходит для локальных окружений или когда нужно быстро протестировать.
Как установить лимит для скрипта командной строки (CLI)?
При запуске php-скрипта передайте параметр -d.
php -d memory_limit=1024M myscript.phpИли установите в php.ini для CLI отдельное значение (обычно выше, чем для веба).
; /etc/php/8.3/cli/php.ini
memory_limit = 2GПроблема:
CLI-скрипт может использовать слишком много памяти, замедляя систему.Решение:
Используйте мониторинг с memory_get_usage() для отладки.Расширенные примеры и команды для настройки памяти PHP
Пример 1: проверка текущего лимита и использование разных единиц
<?php
// Текущий лимит из php.ini
echo "Текущий memory_limit: " . ini_get('memory_limit') . "\n";
// Устанавливаем через ini_set
ini_set('memory_limit', '1G');
echo "Новый лимит: " . ini_get('memory_limit') . "\n";
// Примеры единиц: 256M, 1G, -1 (безлимит), 131072 (в байтах)
?>Текущий memory_limit: 128M Новый лимит: 1G
Пример 2: мониторинг использования памяти
<?php
echo "Использовано: " . memory_get_usage() . " байт\n";
echo "Пиковое использование: " . memory_get_peak_usage() . " байт\n";
// Создание большого массива
$bigArray = range(1, 100000);
echo "После создания массива: " . memory_get_usage() . " байт\n";
?>Использовано: 386920 байт Пиковое использование: 388128 байт После создания массива: 7988344 байт
Пример 3: обработка фатальной ошибки нехватки памяти
<?php
register_shutdown_function(function() {
$error = error_get_last();
if ($error && strpos($error['message'], 'Allowed memory size') !== false) {
echo "Обнаружена ошибка памяти: " . $error['message'] . "\n";
// Логирование или отправка уведомления
}
});
// Имитируем переполнение
$data = str_repeat('A', 1024 * 1024 * 1000); // ~1 ГБ
?>Обнаружена ошибка памяти: Allowed memory size of 134217728 bytes exhausted (tried to allocate ...)
Пример 4: установка лимита через командную строку с проверкой
# Установка лимита в 512M и запуск скрипта
php -d memory_limit=512M -r 'echo ini_get("memory_limit");'
# Результат: 512M512M
Пример 5: конфигурация для PHP-FPM с разными пулами
; В файле пула /etc/php/8.3/fpm/pool.d/www.conf
; Можно задать директивы через php_admin_value
php_admin_value[memory_limit] = 256M
php_admin_value[upload_max_filesize] = 100M
; После редактирования перезапустить FPM(перезапуск сервиса)
Пример 6: динамическое изменение на основе нагрузки
<?php
// Увеличение лимита только при необходимости
if (memory_get_usage() > 100 * 1024 * 1024) { // больше 100 МБ
ini_set('memory_limit', '512M');
}
?>(нет вывода, лимит изменяется)
Пример 7: получение информации из phpinfo()
<?php
phpinfo();
?>В выводе найдите строку memory_limit - это покажет текущее значение и директиву из основного конфига.