Конфигурация memory_limit в PHP

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

Настройка memory_limit в PHP

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

Основной способ: редактирование файла php.ini

Этот метод подходит для серверов, где есть доступ к главному конфигурационному файлу PHP. Изменение в php.ini влияет на все скрипты, запускаемые на сервере, включая CLI и веб-режимы.

; Пример строки в php.ini
memory_limit = 256M

Php ubuntu (php на ubuntu)

Шаги:

  1. Найти файл php.ini. Обычно он расположен в /etc/php/8.x/apache2/php.ini (Linux) или C:\php\php.ini (Windows). Точный путь можно узнать через php --ini или phpinfo().
  2. Открыть файл с правами администратора.
  3. Найти строку memory_limit и изменить значение. Если строки нет, добавить её.
  4. Сохранить изменения и перезапустить веб-сервер (например, sudo systemctl restart apache2).

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

  • После изменения не перезагружен веб-сервер или PHP-FPM - изменения не вступают в силу. Необходим перезапуск.
  • Неправильный синтаксис: вместо memory_limit = 256M написано memory_limit=256M (без пробела) - это может вызвать ошибку при загрузке конфигурации.
  • Значение слишком большое для физической памяти сервера - скрипты могут вызывать сбои системы или out-of-memory.
  • Отсутствие прав на запись в php.ini - требуется сменить владельца или использовать sudo.

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

Использование файла .htaccess (для Apache)

Когда у пользователя нет доступа к глобальному php.ini, но сервер использует Apache с mod_php, можно задать настройки через .htaccess. Это удобно для shared-хостинга.

# В корневом .htaccess
php_value memory_limit 128M
php_value max_execution_time 300

Localhost php (настройка локального сервера php)

Важно: директива php_value работает только если сервер не использует PHP-FPM или CGI. Для последних потребуется другой подход.

Проблемы и ограничения:

  • Директива может быть запрещена в настройках Apache (AllowOverride None). В этом случае изменения проигнорируются.
  • Для PHP-FPM .htaccess не работает - нужно настраивать пул через pool.d.
  • Значение применяется только для файлов в этом каталоге и его подкаталогах.

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

Использование функции ini_set()

Если нужно изменить лимит памяти только для одного скрипта или части скрипта, используется встроенная функция ini_set(). Изменение действует только на текущий запрос и не влияет на другие процессы.

<?
// Установка лимита памяти для данного скрипта
ini_set('memory_limit', '512M');
// Теперь скрипт может использовать до 512 МБ
$data = str_repeat('x', 500 * 1024 * 1024); // выделение 500 МБ
?>

Php windows (php на windows)

Ограничение: функция не сработает, если в php.ini установлен disable_functions или если скрипт уже превышает новый лимит до вызова ini_set.

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

  • ini_set() не может уменьшить лимит, если он уже установлен на более высокое значение другим методом.
  • Попытка установить значение ниже используемой памяти приведет к фатальной ошибке.
  • Если memory_limit отключен в глобальных настройках (значение -1), ini_set не сможет его изменить в некоторых режимах.

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

Использование опции -d при запуске php

Для CLI-скриптов можно задать параметр прямо в команде без изменения конфигурационных файлов. Это полезно для одноразовых задач, крона или тестирования.

php -d memory_limit=1024M my_script.php

Admin php (администрирование php)

Параметр -d определяет значение на время выполнения только этого скрипта. Можно комбинировать с другими директивами.

Проблемы:

  • Не работает для веб-запросов, только для CLI.
  • Если скрипт требует прав на редактирование php.ini, данный метод не подойдет.
  • Значение в команде имеет приоритет над php.ini, но не над ini_set() внутри скрипта.

Как узнать текущее значение memory_limit и объем используемой памяти?

Проверка и мониторинг

Для отладки и контроля потребления памяти полезно использовать функции ini_get(), memory_get_usage() и memory_get_peak_usage().

<?
echo 'Текущий лимит: ' . ini_get('memory_limit') . "\n";
echo 'Использовано памяти: ' . memory_get_usage() / 1024 / 1024 . ' МБ' . "\n";
echo 'Пиковое использование: ' . memory_get_peak_usage() / 1024 / 1024 . ' МБ' . "\n";
?>

Типичные ошибки при интерпретации:

  • memory_get_usage() возвращает память, выделенную самому PHP, а не всей системе. Для оценки полной нагрузки нужно учитывать и другие процессы.
  • Значение в php.ini может быть задано в разных единицах (K, M, G) - функция ini_get возвращает строку, ее нужно преобразовывать.
  • При использовании phpinfo() нужно искать не только memory_limit, но и другие настройки, влияющие на потребление.
- изменить настройки php (изменение настроек php)
- Php ini memory (настройка memory_limit в php)
- Php ini linux (настройка php.ini в linux/ubuntu)

Расширенные примеры настройки и диагностики memory_limit

Пример 1: Изменение лимита внутри скрипта с проверкой

Скрипт демонстрирует вызов ini_set и проверку, удалось ли применить новое значение. Это полезно, когда не уверены, разрешено ли изменять директиву.

Пример
<?
// Пример 1: установка и проверка изменения memory_limit
echo "Начальный лимит: " . ini_get('memory_limit') . "\n";
$result = ini_set('memory_limit', '256M');
if ($result === false) {
    echo "Ошибка: не удалось изменить memory_limit\n";
} else {
    echo "Новый лимит: " . ini_get('memory_limit') . "\n";
}
?>
Начальный лимит: 128M
Новый лимит: 256M

Пример 2: Обработка ошибки исчерпания памяти и конвертация единиц

Показывает, как перехватить фатальную ошибку при превышении лимита и как преобразовать строковое значение memory_limit в байты для анализа.

Пример
<?
// Пример 2: перехват ошибки превышения памяти
try {
    $data = str_repeat('x', 2000 * 1024 * 1024); // 2 ГБ
    echo "Успешно выделили память\n";
} catch (\Throwable $e) {
    echo "Ошибка: " . $e->getMessage() . "\n";
}
// Альтернативный способ: измерение предела
$limit = ini_get('memory_limit');
$limit_bytes = return_bytes($limit);
echo "Лимит в байтах: $limit_bytes\n";
function return_bytes($val) {
    $val = trim($val);
    $last = strtolower($val[strlen($val)-1]);
    $val = (int) $val;
    switch($last) {
        case 'g': $val *= 1024;
        case 'm': $val *= 1024;
        case 'k': $val *= 1024;
    }
    return $val;
}
?>
Ошибка: Allowed memory size of 268435456 bytes exhausted (tried to allocate 2097152000 bytes)
Лимит в байтах: 268435456

Пример 3: Запуск скрипта из командной строки с несколькими параметрами

Использование опции -d для временного переопределения memory_limit и других директив. Результат показывает значения, полученные внутри скрипта.

Пример
<?
// Пример 3: запуск из командной строки с несколькими директивами
// php -d memory_limit=512M -d max_execution_time=60 long_script.php
// Внутри скрипта:
echo "Режим: " . php_sapi_name() . "\n";
echo "memory_limit: " . ini_get('memory_limit') . "\n";
echo "max_execution_time: " . ini_get('max_execution_time') . "\n";
?>
Режим: cli
memory_limit: 512M
max_execution_time: 60

Пример 4: Сравнение значений php.ini и текущих настроек

Функция get_cfg_var возвращает значение из оригинального файла php.ini, игнорируя последующие изменения через ini_set или -d. Это помогает понять, какое значение было базовым.

Пример
<?
// Пример 4: определение приоритета настроек
// Если memory_limit установлен и через php.ini, и через ini_set, и через -d
// Проверим результат:
echo "memory_limit из php.ini (через ini_get): " . ini_get('memory_limit') . "\n";
// Сравнение с get_cfg_var (показывает значение из php.ini, игнорируя изменения)
echo "memory_limit из php.ini (через get_cfg_var): " . get_cfg_var('memory_limit') . "\n";
?>
memory_limit из php.ini (через ini_get): 512M
memory_limit из php.ini (через get_cfg_var): 128M

Пример 5: Измерение потребления памяти при обработке файла

Отслеживание используемой памяти до и после загрузки большого файла в массив. Позволяет оценить, насколько скрипт требователен к памяти, и принять решение о лимите.

Пример
<?
// Пример 5: мониторинг пикового потребления при обработке большого файла
file_put_contents('test.txt', str_repeat('line', 100000));
$start_memory = memory_get_usage();
$file = file('test.txt');
$end_memory = memory_get_usage();
echo "Память до чтения: " . ($start_memory/1024/1024) . " МБ\n";
echo "Память после: " . ($end_memory/1024/1024) . " МБ\n";
echo "Пик: " . (memory_get_peak_usage()/1024/1024) . " МБ\n";
unlink('test.txt');
?>
Память до чтения: 0.42 МБ
Память после: 3.81 МБ
Пик: 4.01 МБ

Настройка memory_limit в PHP - comments

En
Php ini memory (php)