Исправление ошибки "Maximum execution time" в PHP

Александр Кичатов

Почему возникает ошибка

Ошибка maximum execution time появляется когда скрипт работает дольше, чем разрешено в настройках PHP:

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

// Ждём 2 секунды и получаем ошибку
sleep(2);

Результатом работы этого скрипта будет ошибка:

Fatal error:
Maximum execution time of 1 second exceeded in
D:\Programs\OpenServer\domains\test.local\index.php on line 6

Почему скрипт чаще всего выполняется медленно:

  • Слишком много вычислений в коде, которые сервер не может выполнить за разрешённое время
  • Медленные SQL-запросы
  • Медленные внешние запросы к другим сайтам/веб-сервисам
  • Бесконечные циклы или рекурсия

Как исправить ошибку

В каждой ситуации решение индивидуальное. Часто проблему можно решить просто увеличив максимально разрешённое время работы скрипта (разрешено не на всех хостингах).

Увеличение времени работы скрипта в .htaccess (указывается в секундах):

php_value max_execution_time 300

В php.ini:

max_execution_time = 300;

Либо напрямую в PHP:

ini_set('max_execution_time', 300);

// Или так
set_time_limit(300);

У функции set_time_limit есть одна особенность - она начинает отсчёт времени работы скрипта с нуля.

Т.е. если время работы изначально было 10 секунд, а через 5 секунд был выполнен код set_time_limit(20);, то в итоге скрипт будет выполняться не более 25 секунд.

Отлов и обработка ошибки

Хоть ошибка и является фатальной, её появление можно отловить и обработать с помощью функции register_shutdown_function():

<?php
// Отключаем вывод текста ошибки на экран
ini_set('display_errors', 0);

register_shutdown_function(function() {

    $e = error_get_last();

    if($e and $e['type'] == 1) {
        echo 'Фатальная ошибка!';
    }
});

// Устанавливаем макс время - 1 секунду
set_time_limit(1);

// Ждём 2 секунды и получаем ошибку
sleep(2);

При выполнении этого кода на экран выведется сообщение Фатальная ошибка!.

Единственный нюанс - условие $e['type'] == 1 отработает для любых фатальных ошибок, а не только для Maximum execution time.

Комментарии