PHPの実行時間超過エラー対処法
冒頭まとめ PHPで取り込みや集計などの処理を実行すると、次のエラーで止まることがあります。 PHP Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/app/import.php on line 57 PHPに設定された実行時間の上限に達したことを示します。30は設定値の例です。まず失敗した実行環境で max_execution_time を確認し、時間のかかる処理を特定します。 必要な処理量に対して上限が短ければ調整します。ただし、OSやPHPの組み立て方によって時間の数え方が異なり、Webサーバー側にも別の制限があります。PHPの秒数を増やすだけで、必ず完了できるわけではありません。 30秒は必ずしも時計の30秒ではない PHPの公式説明では、max_execution_time の既定値は30秒、CLIの既定値は0です。0はPHP側の実行時間制限を設けない指定です。 一般的な setitimer(ITIMER_PROF) を使う環境ではCPU時間を計ります。この場合、データベースの問い合わせや入出力などで待っている時間は、経過した実時間と同じようには加算されません。 一方、Windowsや、--enable-zend-max-execution-timers を有効にして組み立てたPHPでは実時間を計ります。後者はPHP 8.3以降のスレッド対応の組み立てで既定です。PHP 8.5.12の実装には、Apple SiliconのmacOSなどで実時間のタイマーを使う分岐もあります。 したがって、Linuxなら待ち時間は必ず除外される、Windows以外なら同じ結果になる、とも言い切れません。利用しているOSとPHPの構成を合わせて確認してください。 エラーが出た環境の有効値を確認する Webで失敗した処理と、ターミナルから実行した処理では、実行方式や設定が異なる場合があります。WebのエラーをCLIの設定だけで判断しないようにします。 対象の処理で、次のように実行方式と上限をログへ記録します。 <?php error_log('PHP=' . PHP_VERSION . ' SAPI=' . PHP_SAPI); error_log('max_execution_time=' . ini_get('max_execution_time')); CLI側の確認は次です。 php -v php --ini php -r "echo ini_get('max_execution_time'), PHP_EOL;" CLIの0は変更できない固定値ではありません。PHPのコマンドライン引数の説明には、-d max_execution_time=20 で値を指定する例もあります。アプリ内の set_time_limit() などによって変わっていないかも確認してください。 確認用のコードをWebから誰でも使える状態で残さず、既存のログや管理者用の確認手段を使います。 時間を使っている処理を区切って調べる エラーにあるファイルと行番号を手がかりに、処理の前後へログを追加します。ただし、その行だけが遅いとは限りません。前の処理から積み重なった時間も確認対象です。 実際の経過時間を記録する例です。 <?php $started = hrtime(true); error_log('import: start'); // 調べたい処理をここに置く $elapsed = (hrtime(true) - $started) / 1_000_000_000; error_log('import: elapsed=' . $elapsed . ' seconds'); hrtime()は時間の計測に使う関数です。この例は経過時間を測るため、PHPの上限がCPU時間を計る環境では、その上限と同じ値にはなりません。 ...