[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 メーリングリストの案内