5.

PHP Fatal error: Maximum execution time of 30 seconds exceeded の原因と対処

編集
この記事の要点
  • PHP のスクリプト実行時間が php.ini の max_execution_time(デフォルト 30 秒)を超えた時のエラー
  • 主な原因: 重い DB クエリ / 無限ループ / 大量ループ / 外部 API の応答遅延 / I/O 待ち
  • 応急対処は set_time_limit(0) / ini_set("max_execution_time", 60)。ただし根本対処はクエリ最適化やバッチ化
  • CLI と Web で設定が別。Web は php.ini / .htaccess、CLI は php -d max_execution_time=0
  • Laravel / Symfony では時間のかかる処理は Queue / Job に逃がすのがベストプラクティス

このエラーの概要

PHP は暴走スクリプトでサーバを止めないため、デフォルトで 30 秒以内にスクリプトが完了しないと処理を中断し、次のエラーを吐きます:

Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/html/app.php on line 42
PHP Fatal error:  Maximum execution time of 30 seconds exceeded ...

このタイムアウトは CPU 時間 のみ計測されます(PHP < 7.1 では)。sleep() や外部リソース待ちは含まれないため、本当の wall-clock 時間とは異なる場合があります(PHP 7.1+ では wall-clock を計測)。

原因の切り分け

原因典型例対処方針
重い DB クエリJOIN 連発、INDEX 無しEXPLAIN で確認 → INDEX 追加
無限ループwhile (true) の脱出条件バグロジック修正
大量データの一括処理10 万件を foreach で処理分割 / バッチ化 / Queue 化
外部 API の応答遅延連続して API 呼出並列化 / 非同期 / タイムアウト短縮
大容量ファイル読込file_get_contents で巨大ファイルストリーム読込(fgets
正規表現の暴走Catastrophic Backtracking正規表現修正 / 別手段

対処1: スクリプト内で時間延長

最も早い応急対処は、スクリプト先頭で次のいずれかを呼ぶことです:

注意: safe_mode 有効時 / 一部のレンタルサーバ / PHP-FPM ではこの方法が効かないことがあります。

対処2: php.ini で全体設定

; /etc/php/8.2/fpm/php.ini または /etc/php/8.2/cli/php.ini
max_execution_time = 60

; Web からのアップロード時間
max_input_time = 60

; メモリも合わせて
memory_limit = 256M

変更後は systemctl reload php8.2-fpm または Apache 再起動が必要です。CLI と FPM で php.ini が別なので両方確認:

# CLI で使われている php.ini
php --ini

# Web (FPM) で使われている php.ini
php -i | grep "Loaded Configuration File"
# または  を実行

対処3: .htaccess で個別設定(Apache + mod_php)

# .htaccess(プロジェクトルートに配置)

    php_value max_execution_time 120
    php_value max_input_time 120
    php_value memory_limit 256M

PHP-FPM 環境では .htaccessphp_value は効きません。FPM のプール設定または .user.ini を使います:

; .user.ini(公開ディレクトリに配置、5 分キャッシュ)
max_execution_time = 120
memory_limit = 256M

対処4: CLI での実行時間

バッチ処理を CLI で動かすとき、php.ini の CLI 用設定または引数で個別指定できます:

# 1 回の実行のみ無制限化
php -d max_execution_time=0 batch.php

# CLI 用 php.ini を確認
php --ini
# /etc/php/8.2/cli/php.ini に対して
# max_execution_time = 0 と書くのが定石(CLI は基本無制限)

対処5: PHP-FPM の request_terminate_timeout

PHP-FPM には独自のタイムアウト request_terminate_timeout もあり、こちらは php.ini の max_execution_time より優先 されます:

; /etc/php/8.2/fpm/pool.d/www.conf
request_terminate_timeout = 120s

; 0 にすると php.ini の max_execution_time を尊重
request_terminate_timeout = 0

FPM のさらに上流(Nginx / Apache mod_proxy_fcgi)のタイムアウト(fastcgi_read_timeout / ProxyTimeout)も延ばす必要があります。

対処6: Laravel / Symfony で Queue に逃がす(根本対処)

そもそも Web リクエスト中に長時間処理を走らせるのは UX 的にもサーバ的にも悪手です。非同期ジョブに逃がすのが現代的な解です:

クエリ最適化の例(最も多い原因)

id)->get();  // 10000 回
}

// 良い例: eager loading で 2 回
$users = User::with('orders')->get();
foreach ($users as $user) {
    $orders = $user->orders;  // 追加クエリなし
}

// チャンク処理で大量レコード
User::chunk(1000, function ($users) {
    foreach ($users as $user) {
        processUser($user);
    }
});

FAQ

Q: set_time_limit(0) しても効かない
A: safe_mode が有効、または PHP-FPM の request_terminate_timeout が短い、または上流(Nginx 等)でタイムアウトしている可能性。phpinfo() で実効値を確認してください。

Q: Web 画面が「504 Gateway Timeout」になる
A: PHP は動いていても Nginx 側で切断。fastcgi_read_timeout 300;location ~ \.php$ に追加。

Q: ブラウザだけ切れて PHP は動き続けている?
A: 可能性あり。ignore_user_abort(true) を入れていると、ブラウザを閉じても PHP は最後まで実行されます。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. Fatal error: Maximum execution time of 30 seconds exceeded in...
  2. Fatal error: Uncaught Error: Cannot use object of type stdClass as array in ...
  3. Warning: Use of undefined constant ... - assumed '...' (this will throw an Error)
  4. ERROR: Call to undefined method Maatwebsite\Excel\Excel::load()
  5. Maximum execution time of 30 seconds exceeded
  6. Your requirements could not be resolved to an installable set of packages. ... To enable extensions, verify that they are enabled in your .ini files:
  7. could not find driver
  8. the requested PHP extension mbstring is missing from your system.
  9. the requested PHP extension dom is missing from your system.
  10. A non well formed numeric value encountered
  11. Warning: Cannot modify header information - headers already sent by ...
  12. php_network_getaddresses: getaddrinfo failed: Name or service not known
  13. XMLWriter::openUri(): Unable to resolve file path
  14. Object of class stdClass could not be converted to string
  15. Class 'Google_Service_Youtube' not found