#Что означает ошибка
Fatal error: Maximum execution time of 30 seconds exceeded
PHP ограничивает время выполнения скрипта (по умолчанию 30 секунд), чтобы зависший или тяжёлый скрипт не занимал процесс. При превышении выдаётся Fatal error: Maximum execution time of 30 seconds exceeded. Простое повышение лимита помогает только для разовых задач (импорт, резервная копия); если ошибка возникает на обычной странице, нужно найти причину медленной работы: запрос к базе, внешний API, бесконечный цикл.
#Причины и решения
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Тяжёлая операцияИмпорт, обработка изображений, архивация. | Ошибка при конкретном действии. | Увеличьте лимит или выполняйте частями. |
| Медленный запрос к базеНет индекса или большая выборка. | EXPLAIN показывает полный просмотр. | Добавьте индекс, оптимизируйте. |
| Зависший внешний запросВнешний сервис не отвечает. | Скрипт ждёт ответа cURL. | Установите таймаут. |
| Бесконечный циклОшибка в логике. | Нагрузка на CPU. | Исправьте код. |
#Пошаговое решение
- Определите, где тормозитОткройте закрытый журнал ошибок PHP в панели сайта или конфигурации PHP-FPM и найдите строку
Maximum execution time of ... exceededс файлом, номером строки и временем. Откройте этот файл в редакторе, добавьте временное измерениеmicrotime(true)перед и после предполагаемого долгого участка, отправляя разницу черезerror_log(), без пользовательских данных. Если строка указывает на ожидание БД или сети, исправлять нужно именно этот вызов; увеличение лимита лишь скрывает симптом. - Проверьте медленные запросыЕсли замедление происходит на SQL-запросе, найдите его в коде и выполните диагностический
EXPLAINв штатном клиенте вашей СУБД на испытательной базе. Для MySQL администратор может включить журнал медленных запросов с ограниченной длительностью и правами доступа, затем проверить индексы и полный перебор таблицы. Не включайте подробное журналирование всех запросов надолго на нагруженном рабочем сервере. - Задайте таймауты cURLЕсли код обращается к HTTP API через cURL, найдите
curl_setopt_arrayи задайтеCURLOPT_CONNECTTIMEOUT(ожидание подключения, например 5 секунд) иCURLOPT_TIMEOUT(всё выполнение, например 20 секунд) с учётом требований сервиса. При ошибке логируйтеcurl_errno()и длительность запроса; не делайте бесконечные повторы, которые сами приводят к истечению общего времени PHP. - Увеличьте лимит в php.iniТолько если тяжёлая операция действительно должна занимать больше лимита и ресурсы позволяют, в конфигурации фактического обработчика сайта (PHP-FPM и CLI могут иметь разные
php.ini) изменитеmax_execution_timeна согласованное значение. Перед правкой сохраните исходную настройку; в панели хостинга используйте поле настроек PHP сайта, если оно есть. Перечитайте конфигурацию нужного PHP-FPM, затем проверьте установленное значение на тестовом запросе; не увеличивайте все таймауты автоматически до 300. - Увеличьте лимит в скриптеАльтернативно для контролируемого одиночного скрипта можно вызвать
set_time_limit(120);до длительного вычисления, если функция разрешена конфигурацией. Она перезапускает счётчик лимита времени выполнения, но не устраняет сетевые или серверные ограничения и не гарантирует завершения запроса за 120 секунд. Для пользовательских HTTP-запросов с большой нагрузкой лучше вынести работу в фоновое задание. - Проверьте лимиты веб-сервераПроверьте журналы Nginx/Apache и прокси: клиент мог получить 504 раньше, чем PHP достиг собственного
max_execution_time. У Nginx для FastCGI естьfastcgi_read_timeout, но его значение регулирует ожидание между чтениями, а не общий предел длительности задачи. Меняйте только нужную директиву конкретного сайта после измерений и перезагружайте конфигурацию штатно с проверкой синтаксиса; не завышайте глобальные таймауты для всех сайтов. - Вынесите задачуЕсли задача импортирует много записей или формирует отчёт, перенесите выполнение в отдельную CLI-команду или очередь заданий с журналом прогресса, ограничением параллельности и восстановлением после сбоя. На Linux администратор может запускать её через cron/systemd timer, но обязательно с отдельным пользователем и понятным путём к PHP. Не переносите напрямую HTTP-контроллер с паролями в публичную командную строку.
- Разбейте на пакетыРазбейте обработку данных на небольшие подтверждаемые порции (например, 100 записей для начала), после каждой фиксируйте позицию и результат в БД. При сбое повторная обработка не должна создавать дубли: используйте уникальные ключи и транзакции. Сравните время одной порции и потребление памяти; затем увеличивайте размер только если это улучшает производительность. Проверьте, что окончательная задача завершилась и все записи обработаны.
- Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
Помните, что max_execution_time не включает время ожидания внешних вызовов на Linux (системные вызовы вроде sleep, curl, запросы к БД не учитываются в некоторых конфигурациях), поэтому таймауты внешних запросов нужно задавать отдельно. На виртуальном хостинге лимит может быть жёстким и не меняться — тогда единственный путь это оптимизация или переход на VPS. Для WordPress тяжёлые операции (импорт, резервное копирование) лучше запускать через WP-CLI: wp import. Документация — .