処理の実行と進捗の更新
Progressアクションは実際の処理と、処理の進捗の送信を行います。
class IndexController extends Zend_Controller_Action { ... public function progressAction() { /* (1)HTMLの出力はしない */ $this->_helper->viewRenderer->setNoRender(); /* 必要なコンポーネントの読み込み */ require_once('Zend/ProgressBar.php'); require_once('Zend/ProgressBar/Adapter/JsPush.php'); /* (2)アダプタの作成 */ $adapter = new Zend_ProgressBar_Adapter_JsPush(); /* (3)本体の作成 */ $progressbar = new Zend_ProgressBar($adapter, 0, 10); /* 次のループを実行している間にプログレスバーが進む */ for ($i = 1; $i < 11; $i++) { /* (4)ここで処理を行う */ sleep(1); /* (5)進捗の送信 */ $progressbar->update($i); } /* (6)処理の終了の送信 */ $progressbar->finish(); } }
このProgressアクションは通常のアクションのようにHTMLファイルを出力するのではなく、進捗に応じてJSONを出力します。そこでまず(1)で通常のようにHTMLの出力は行わないことを指定しています。
この後の流れはコンソールアプリと同じように(2)(3)Zend_ProgressBarのアダプタと本体を作成し、(5)進捗を送信し、(6)処理の終了を送信する処理の流れになっています。前のサンプルと違う点としては(2)で作成しているアダプタがZend_ProgressBar_Adapter_JsPushクラスになっていることくらいです。
ここの(5)でZend_ProgressBarのupdateメソッドが呼び出されると、サーバ側からクライアント側に次のようなJSON形式のデータで進捗が送信されます。
<script type="text/javascript">parent.Zend_ProgressBar_Update({"current":9,"max":10,"percent":90,"timeTaken":8,"timeRemaining":1,"text":null});</script><br />
次は、このデータを受け取って表示する仕組みを見てみます。
文字による進捗の表示
リスト4にあるように、iframeの親ページ(つまり表示されているページ)のZend_ProgressBar_Update関数に進捗状況が渡されます。それではまず、ここで渡されている情報をそのままテキストとして表示してみましょう。
<script type="text/javascript"> <!-- function Zend_ProgressBar_Update(data) { //(1)zend-progressbar-info の内容を更新 document.getElementById('zend-progressbar-info').value = data.percent + "% " + data.current + "/" + data.max + " " + data.timeTaken + "s elapsed (" + data.timeRemaining + "s remaining)" ; } --> </script> ... <!-- (2)進捗状況を表示するためのスペース --> <input id="zend-progressbar-info" type="text" value="progress" size="40">
(1)では、Zend_ProgressBarから受け取った情報が格納されているdata変数を利用して、ページ内にあるフォームのテキストボックス(2)の内容を更新しています。表示されている内容は次のとおりです:
要素名 | 意味 |
current | 進捗の値 |
max | 進捗の値の最大値 |
percent | 進捗の%表示(100*current/max) |
timeTaken | 経過時間 |
timeRemaining | 予想される終了までの時間 |
text | 進捗に関するコメント(指定されている場合のみ) |
これを画面に表示したものが図2です。
これで進捗を受け取って表示することができました。