[PHP-users 14548]Re: set_time_limitについて
Reiji Matsumoto
matsumoto @ spline.oc.to
2003年 4月 9日 (水) 21:55:11 JST
Matsumoto @ Spです。
まずset_time_limit()ですが、今回の場合は利用できないと思います。
IEが自分自身でタイムアウトしてしまうので、いくらサーバー側で
タイムアウトを無限に設定しても回避できません。
多くのブラウザは一定時間、サーバーから何も応答が無い場合に接続を
遮断します。ですので少しでもいいから数秒おきに何か出力してやれば
良いのです。
私の場合あまり見た目にこだわらなくていい場合、
以下のようにしています。
print "処理中ですしばらくお待ち下さい<br>";
set_time_limit(0); // スクリプトの実行時間を無限にする
hogejob_start(); // 時間のかかる処理をキック
ob_end_flush();// 出力バッファリングの終了
flush(); // これまでの内容をブラウザに送信
ob_implicit_flush(); // 出力関数毎にブラウザに送信するようにする
while(hogejob_status()) // 処理が終わったかどうかを判断
{
print ".\n";
sleep(10);
}
print "<br>complete";
hogehoge(); // 後処理
これで10秒おきにピリオドが1個送信されますので、接続が維持され、かつ
ブラウザの見た目にも変化を及ぼす事が可能です。ピリオドの後の改行ですが、
ブラウザによっては改行コードを検出するまでレンダリングを抑止する事が
あるので入れておいた方が良いと思います。
ブラウザのJavascriptと連動させれば見た目もかなりいい感じにできるかも知
れません。
問題点としては以下のような物があります。
1.キックの処理が複雑
ポーリングさせながら文字を出力しなくてはならないため、時間のかかる処理を
実行する時、開始処理を行い即座に処理を返してもらい、以後終了判定処理をコー
ルする必要があります。EXCELのコンポーネントにその機能が備わっているか、
ちょっと分かりません。ラッパーコンポーネントを開発し、同様の機能を実現する
事は可能だと思います。
2.文字コードが変わる事がある
出力バッファリングを終了する事によりob_start()で設定したコールバック関数
のサービスが受けられなくなります。そのため、処理開始前まではSJISで文字コード
を送信していたのに、処理開始後はEUC-JPで文字コードが送信されてしまう等の
問題が発生する場合があります。適切な文字コード変換が必要になります。
3.接続が切れる場合が無きにしもあらず
どんなに工夫してもユーザーがブラウザを閉じてしまえば接続が切れてしまいま
す。
その時、処理中のプロセスをどう処理するかと言う問題があります。基本的に、
ignore_user_abort() で接続が切れた後も処理を継続するようにしておくと良い
と思います。
現在、メルマガ配信用のWEBアプリケーションに上記処理を実装しています。
ピリオドだけでは寂しいので、処理中のメール数等を表示しています。
メルマガならsend_mailの実行回数をカウントするだけなので楽なのですが、
EXCELのコンポーネントと通信する上で結構面倒な事があるかも知れませんね。
ご参考までと言う事で…。
PHP-users メーリングリストの案内