- ベストアンサー
PHPスクリプト内で処理時間を判定する方法
- PHPスクリプト内で処理時間を計測し、一定時間を超えた場合にエラーを出力する方法について複数の方法があります。
- 一つの方法は、処理の開始時に現在の時刻を取得し、処理の終了時に再度現在の時刻を取得し、時間の差を計算する方法です。
- もう一つの方法は、set_time_limit()関数を使用して処理の最大実行時間を設定し、処理がその時間を超えた場合にエラーを出力する方法です。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
マニュアルに while setting the set_time_limit(), the duration of sleep() will be ignored in the execution time. ってあるので、sleep()で実験したのではだめなようです。 ためしに <?php set_time_limit(2); for ( $i = 0 ; $i < 40; $i++) { echo "$i:<BR>\n"; for($j=0;$j<200000;$j++) $k=$i+$j; } ?> で実験してみると、、 PHP Fatal error: Maximum execution time of 2 seconds exceeded in {パス} on line 5 のエラーをだしてちゃんと2秒超えたあたりで処理を中断してくれました。 (エラー出すださないは、別途制御できますが)
その他の回答 (2)
- superside0
- ベストアンサー率64% (461/711)
set_time_limit(); http://php.net/manual/ja/function.set-time-limit.php を使うのが簡単だと 思います。 コールした時点からの経過時間の設定なので αの処理を最大30秒に制限 βの処理を最大30秒に制限 とそれぞれ設定したいなら、 set_time_limit(30); α処理 set_time_limit(30) β処理 って感じです。 タイムアウトしたときにメッセージを出したいなら register_shutdown_function() で終了時に自動実行するfunctionを登録して、 そのなかで、本来の処理の最後で代入するglobalのフラグ変数をみて、 フラグがセットされてないときは、タイムアウト処理時だとして その場合のみメッセージを出すようにしてはどうでしょう。
- ky072
- ベストアンサー率60% (85/140)
αの具体的な内容や、時間がかかる理由によって、 適切な書き方はまちまちです。 基本的な考え方としては、αの処理を細切れにして、 都度、時間チェックをしてタイムアウト処理をする必要があります。 ループがあれば、その中で毎回時間をチェックして、 30秒を経過した時点で処理を打ち切ります。 また、単体で時間がかかる恐れのある関数には、 多くの場合、タイムアウトを指定するオプションや、 ノンブロッキングモードが提供されています。 例えば http の file_get_contents() であれば、 stream_context_create() で timeout オプションを指定します。 ftp_get() であれば ftp_nb_get() に置き換えます。 ソケット通信であれば stream_set_timeout() や stream_set_blocking() を使います。 最後に、あまり推奨できませんが、 pcntl_alarm() を使う方法もあります。 ─ $tout=false; declare(ticks=1); function sig($sig){global $tout; $tout=true;} pcntl_signal(SIGALRM, 'sig'); pcntl_alarm(30); while(!$tout){echo '.'; sleep(1);} echo "done.\n";
お礼
お答えいただきありがとうございます。 確かに単体で時間のかかる処理は時間制御が指定できますね。 自分はこれらの処理をマルチプロセスやらで色々と絡んだものをやろうと思っておりまして、 そこでそのグループにて時間指定をしようかと思っておりました。 もう一度単体での時間制御を見直してスクリプトを考えてみます。 今まで自分にそのような経験が無かっただけで知らないのですが、例えばDBだとか、PECLのmemcacheとかの接続の際とかで何らかの理由で時間がかかった場合はどうなるのでしょうか? MySQLなどPDOで書いてると、時間制御の為のオプションとかあったかな?とうろ覚えなのですが。 max_execution_timeとかで指定してある時間が過ぎたりすると、全体的にエラーになって、その後に処理の分岐などは出来るのかな、とか今思ったのですが。 pcntl_alarm()、自分は避けていた面もあるのですが、この際ちょっと学習してみます。 教えていただきありがとうございます。
お礼
お答え頂きましてありがとうございます。 set_time_limit()を使うという発想はありませんでした。 一応自分でCLIにて(自分は最近CLIで使うことが多いもので)書いてみたのですが、 何故か自分の環境ではset_time_limit()が思ったような挙動をしませんでした。 セーフモードでもないのですが。 <?php if( !ini_get('safe_mode') ){ set_time_limit(5); } else { die("safe_modeですよ\n"); } function aaa() { for($i=0; $i<10; $i++) { echo $i . "秒経過\n"; sleep(1); } } aaa(); サンプルがいまいち良く分からなかったので、単純にこんな感じで買いてみたのですが、 5秒以上かかっても普通に実行されておりました。 使い方が悪いのかもしれませんが。