Максимальный объем памяти PHP: конфигурирование

Раздел: Администрирование PHP -> Настройка конфигурации PHP

Лимит памяти в PHP: настройка и управление

Основной способ: изменение php.ini

Как увеличить лимит памяти для всех PHP скриптов на сервере?

Самый надёжный метод - отредактировать главный конфигурационный файл PHP (php.ini). Найдите директиву memory_limit и установите нужное значение, например 256M. После изменений обязательно перезапустите веб-сервер (Apache, Nginx) или PHP-FPM, чтобы новый лимит вступил в силу.

; php.ini
memory_limit = 256M

Проверить текущее значение можно с помощью функции phpinfo() или

<?php
echo ini_get('memory_limit');
?>

Типичные проблемы:

  • Файл php.ini недоступен для редактирования (на shared хостинге).
  • Изменения не применяются, если не перезагружен веб-сервер.
  • В CLI используется отдельный php.ini (например, /etc/php/8.2/cli/php.ini).

Решение: убедитесь, что редактируете правильный файл (определите через php --ini в CLI или phpinfo() в браузере). После правки выполните sudo systemctl restart apache2 или sudo systemctl restart php8.2-fpm.

Через файл .htaccess (для Apache с mod_php)

Как настроить лимит памяти для отдельной директории?

Если используется Apache и PHP работает как модуль, можно добавить директиву в файл .htaccess в корне нужной папки:

# .htaccess
php_value memory_limit 128M

Проблемы и ошибки:

  • Сервер может вернуть ошибку 500, если директива php_value не разрешена настройками Apache (AllowOverride не включает Options).
  • Не работает для PHP в режиме CGI/FastCGI (тогда используйте .user.ini).
  • Значение применяется только для файлов внутри этой директории.

Решение: проверьте конфигурацию Apache, в блоке <Directory> должно быть AllowOverride All или AllowOverride Options. При ошибке 500 временно переименуйте .htaccess.

Файл .user.ini (для CGI/FastCGI и PHP-FPM)

Как ограничить память для конкретной папки, если PHP работает через CGI?

Поместите файл .user.ini в нужную директорию с содержимым:

; .user.ini
memory_limit = 64M

PHP будет читать этот файл при запуске скриптов в этой папке и её подпапках.

Типичные ошибки:

  • Файл .user.ini не работает, если PHP выполняется как модуль Apache.
  • Изменения применяются не сразу, а только при новом запросе (см. директиву user_ini.filename в php.ini).
  • В некоторых окружениях (например, с opcache) нужно сбрасывать кеш.

Функция ini_set() в коде

Как изменить лимит памяти только для текущего скрипта?

Внутри PHP скрипта можно вызвать ini_set('memory_limit', '256M'). Однако это сработает только до момента превышения текущего лимита.

<?php
ini_set('memory_limit', '256M');
echo 'Новый лимит: ' . ini_get('memory_limit');
?>

Проблемы:

  • Если память уже исчерпана, ini_set() не поможет - скрипт упадёт с фатальной ошибкой.
  • Нельзя уменьшить лимит ниже уже выделенного объёма.
  • Функция может быть отключена директивой disable_functions.

Решение: вызывайте ini_set() в самом начале скрипта до любых ресурсоёмких операций.

Командная строка CLI с параметром -d

Как временно задать лимит памяти при запуске скрипта из командной строки?

При выполнении PHP скрипта в CLI используйте флаг -d для установки директивы:

php -d memory_limit=512M script.php

Этот лимит действует только для одного вызова и не влияет на другие процессы.

Ошибки:

  • Параметр -d не работает для php.ini директив, помеченных как PHP_INI_SYSTEM (например, memory_limit является PHP_INI_ALL, поэтому работает).
  • При использовании оболочек (shell) нужно экранировать кавычки, если значение содержит пробелы.

Настройка в пуле PHP-FPM

Как установить лимит памяти для конкретного пула PHP-FPM?

В конфигурационном файле пула (например, /etc/php/8.2/fpm/pool.d/www.conf) добавьте строку:

php_admin_value[memory_limit] = 256M

После изменения перезагрузите PHP-FPM. Это значение будет применено ко всем скриптам, обслуживаемым данным пулом.

Типичные проблемы:

  • Если указать php_value[memory_limit] вместо php_admin_value, пользователь сможет переопределить лимит через ini_set().
  • Необходимо синхронизировать настройки пула с основным php.ini, так как php_admin_value имеет высший приоритет.

Решение: используйте php_admin_value для жёсткого ограничения, если требуется.

Расширенные примеры работы с лимитом памяти

Ниже приведены нестандартные сценарии и примеры кода с результатами.

Динамическое определение лимита на основе доступной системы

Скрипт получает общую память сервера и устанавливает лимит как долю от неё.

Пример
<?php
// Определяем общую физическую память (в байтах)
$totalMemory = trim(shell_exec("grep MemTotal /proc/meminfo | awk '{print $2}'")) * 1024;
// Устанавливаем 25% от общей памяти
$limit = round($totalMemory * 0.25);
ini_set('memory_limit', $limit);
echo 'Лимит памяти установлен: ' . ini_get('memory_limit');
?>
Лимит памяти установлен: 256M

Отладка пикового потребления памяти

Используйте memory_get_peak_usage() для поиска узких мест.

Пример
<?php
echo 'Начало: ' . memory_get_usage() . ' bytes\n';
$data = range(1, 100000);
echo 'После создания массива: ' . memory_get_usage() . ' bytes\n';
echo 'Пик: ' . memory_get_peak_usage() . ' bytes';
?>
Начало: 397840 bytes
После создания массива: 14542984 bytes
Пик: 14543944 bytes

Обработка фатальной ошибки превышения памяти

Зарегистрируйте функцию завершения для логирования.

Пример
<?php
register_shutdown_function(function() {
    $error = error_get_last();
    if ($error !== null && $error['type'] === E_ERROR) {
        if (strpos($error['message'], 'Allowed memory size') !== false) {
            // Логируем в файл
            file_put_contents('/tmp/memory_errors.log', date('Y-m-d H:i:s') . ' ' . $error['message'] . PHP_EOL, FILE_APPEND);
            echo 'Критическая ошибка памяти зафиксирована.';
        }
    }
});
// Действие, которое вызовет переполнение
$big = str_repeat('X', 1024 * 1024 * 300); // 300 MB
?>
Критическая ошибка памяти зафиксирована.

Установка лимита через переменные окружения

В Docker или CI можно передавать лимит через переменную окружения.

Пример
<?php
$envLimit = getenv('PHP_MEMORY_LIMIT');
if ($envLimit !== false) {
    ini_set('memory_limit', $envLimit);
}
echo 'Текущий лимит: ' . ini_get('memory_limit');
?>
Текущий лимит: 512M

Запуск скрипта с ограничением через .env файл

Пример для CLI с загрузкой настроек из .env.

Пример
# .env
PHP_MEMORY_LIMIT=256M
Пример
#!/bin/bash
source .env
php -d memory_limit=$PHP_MEMORY_LIMIT script.php
(успешный вывод скрипта)

Сравнение приоритетов настроек

Демонстрация приоритета: php_admin_value > php.ini > .htaccess > ini_set(). Выполните скрипт в разных конфигурациях.

Пример
<?php
echo ini_get('memory_limit');
?>

Результат при разных настройках:

  • php_admin_value[memory_limit] = 256M: вывод 256M
  • в php.ini memory_limit = 128M: вывод 128M (если нет переопределения)
  • .htaccess с php_value memory_limit 64M: вывод 64M
  • вызов ini_set('memory_limit','32M') в начале скрипта: вывод 32M

Если установлен php_admin_value, все остальные методы игнорируются.

Лимит памяти в PHP - comments

En
Php memory limit (php)