Управление временем работы скриптов PHP через max_execution_time

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

Основные способы настройки max_execution_time

Наиболее эффективное решение

Для изменения максимального времени выполнения скрипта в PHP рекомендуется использовать функцию set_time_limit() или директиву ini_set('max_execution_time', ...). Эти методы позволяют задать ограничение непосредственно в коде, не затрагивая глобальные настройки сервера. При вызове set_time_limit(30) таймер сбрасывается и начинает отсчёт заново. Это удобно, когда нужно продлить время выполнения в середине работы скрипта.

<?php
// Установка времени выполнения 60 секунд
set_time_limit(60);

// Альтернативный способ с ini_set
ini_set('max_execution_time', 60);

// Выполнение длительной операции
sleep(2);
echo "Скрипт выполнен за 2 секунды.";
?>

Php open basedir (директива open_basedir в php)

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

При использовании ini_set изменение может не сработать, если скрипт работает в режиме безопасного режима (устарело) или если значение уже превышено. В некоторых SAPI (например, PHP-FPM) директива может быть переопределена конфигурацией пула. Также следует помнить, что set_time_limit() не продлевает время выполнения, если скрипт уже превысил лимит.

Как изменить max_execution_time через php.ini?

Изменение глобального значения для всех скриптов на сервере производится в файле php.ini. Настройка применяется после перезагрузки веб-сервера или PHP-FPM.

; Установить 120 секунд
max_execution_time = 120

Php max execution (максимальное время выполнения скрипта в php (max_execution_time))

После изменения перезагрузите сервер:
sudo systemctl restart apache2
sudo systemctl restart php-fpm

Php max vars (максимальное количество переменных в php (max_input_vars))

Возможные ошибки

Если после изменения php.ini значения не обновляются, проверьте, какой файл php.ini загружен (вызов phpinfo()). Возможно, используется конфигурация пула (для FPM) или .htaccess переопределяет настройку.

Как установить лимит через .htaccess?

Для серверов Apache с mod_php или CGI/FastCGI можно задать директиву в .htaccess.

# Установить 300 секунд
php_value max_execution_time 300

Проблемы с .htaccess

Директива php_value разрешена не во всех контекстах (требуется AllowOverride Options). Для PHP-FPM через Apache директивы .htaccess игнорируются, вместо них нужно настраивать пул.

Как отключить ограничение времени (установить бесконечное выполнение)?

Для скриптов, которые должны работать без временного лимита, можно установить значение 0.

set_time_limit(0);
// или
ini_set('max_execution_time', 0);

Риски безопасности

Отключение лимита может привести к зависанию скрипта и перегрузке сервера. Рекомендуется использовать только для коротких операций с контролем через другие механизмы (например, тайм-аут базы данных).

Как настроить max_execution_time в PHP-FPM pool?

В конфигурации пула (например, /etc/php/8.2/fpm/pool.d/www.conf) можно задать параметры.

; Значение 600 секунд
pm.max_execution_time = 600
; или
request_terminate_timeout = 600

Различие параметров

Параметр pm.max_execution_time влияет на время исполнения скрипта в пуле, а request_terminate_timeout жестко обрывает процесс, если скрипт превысил лимит. Второй вариант более надёжен.

Как проверить текущее значение max_execution_time?

Можно использовать ini_get() или проанализировать вывод phpinfo().

echo 'Текущее ограничение: ' . ini_get('max_execution_time') . ' секунд';
Текущее ограничение: 30 секунд

Как обработать превышение времени выполнения?

При выходе за лимит PHP генерирует фатальную ошибку. Её можно перехватить с помощью register_shutdown_function или установить пользовательский обработчик ошибок.

register_shutdown_function(function() {
    $error = error_get_last();
    if ($error && $error['type'] === E_ERROR) {
        // Если ошибка связана с max_execution_time
        if (strpos($error['message'], 'Maximum execution time') !== false) {
            echo "Скрипт превысил лимит времени.\n";
            // Логирование, запись в БД и т.д.
        }
    }
});
set_time_limit(1); // Заведомо мало
while (true) {}
?>
Скрипт превысил лимит времени.

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

Пример 1. Продление таймера в цикле

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

Пример
<?php
// Обработка 1000 записей с limit 5 секунд на итерацию
set_time_limit(0); // отключаем общий лимит для безопасности? Нет, лучше продлевать
for ($i = 0; $i < 1000; $i++) {
    // Каждые 10 итераций сбрасываем таймер на 30 секунд
    if ($i % 10 === 0) {
        set_time_limit(30);
    }
    // Выполнение тяжелой операции
    usleep(50000); // 0.05 сек
}
echo "Готово";
?>
Вывод: "Готово" (скрипт завершился без превышения лимита)

Пример 2. Использование try-catch для обработки ошибки превышения (эмуляция)

Фатальная ошибка не может быть перехвачена try-catch, но можно использовать register_shutdown_function вместе с error_get_last.

Пример
<?php
// Имитация длительной работы
function heavyTask() {
    while (true) {
        // Делаем что-то
    }
}

register_shutdown_function(function() {
    $lastError = error_get_last();
    if ($lastError !== null && $lastError['type'] === E_ERROR) {
        echo ""Поймана фатальная ошибка: " . $lastError['message'] . "\n"";
        exit;
    }
});

set_time_limit(2);
heavyTask();
?>
Поймана фатальная ошибка: Maximum execution time of 2 seconds exceeded in ...

Пример 3. Настройка через .htaccess для конкретного каталога

В каталоге /admin/ скрипты могут требовать больше времени.

Пример
# .htaccess в папке /admin/
php_value max_execution_time 600
php_value memory_limit 256M

Пример 4. Сравнение поведения в CLI и веб-среде

В командной строке max_execution_time по умолчанию равно 0 (без ограничения). Проверим:

Пример
$ php -r 'echo ini_get("max_execution_time");'
0

Пример 5. Использование PHP-FPM request_terminate_timeout для жесткого контроля

Пример
# /etc/php/8.2/fpm/pool.d/www.conf
request_terminate_timeout = 60s
; Если скрипт не завершится за 60 секунд, процесс будет уничтожен SIGTERM

Пример 6. Пользовательская функция для безопасного выполнения с лимитом

Пример
<?php
function executeWithTimeLimit(callable $callback, int $timeLimitSeconds) {
    $shutdown = function() use ($timeLimitSeconds) {
        $error = error_get_last();
        if ($error !== null && $error['type'] === E_ERROR && stripos($error['message'], 'Maximum execution time') !== false) {
            // Логируем и возвращаем false
            echo "Функция превысила лимит в {$timeLimitSeconds} секунд.";
        }
    };
    register_shutdown_function($shutdown);
    set_time_limit($timeLimitSeconds);
    return $callback();
}

// Использование
$result = executeWithTimeLimit(function() {
    // Долгий код
    sleep(100);
    return true;
}, 10);
?>
Функция превысила лимит в 10 секунд.

Максимальное время выполнения скрипта в PHP (max_execution_time) - comments

En
Php max execution (php)