Управление объемом выделяемой памяти для PHP: варианты и рекомендации

Раздел: Администрирование PHP -> Конфигурация сервера 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");'
# Результат: 512M
512M

Пример 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 - это покажет текущее значение и директиву из основного конфига.

Настройка памяти PHP - comments

En
Php memories (php)