Webアプリでの利用
Zend_ProgressBarをWebアプリで利用するためのアダプタは2種類準備されています。この 2つのアダプタの違いは、進捗の表示を更新するタイミングを、サーバ側、クライアント側のどちらが管理するかの違いです。サーバ側が管理するプッシュ型はZend_ProgressBar_Adapter_JsPushクラス、クライアント側が管理するプル型はZend_ProgressBar_Adapter_JsPullクラスになります。どちらのアダプタを利用した場合でもJSON形式で処理の進捗が送信され、それをクライアント側のJavaScriptで処理する仕組になっています。
ここではまず、プッシュ型のZend_ProgressBar_Adapter_JsPushクラスを利用した方法について解説します。基本はコンソールアプリと同じですが、Webアプリでは処理がサーバ側とクライアント側に分かれているので多少複雑になっています。ここで、IndexコントローラのProgressアクションの進捗状況をプログレスバーで表示する例を考えます(図1)。
図1での処理の流れは次のようになります。まずWebページに埋め込まれたiframeタグ内のページが、(1)サーバ側の処理(Progressアクション)を呼び出します。サーバ側は処理を開始するとともに、(2)Zend_ProgressBarのオブジェクトが必要に応じて進捗を先程のiframeタグ内のページに送信します。この進捗はそのまま(3)JavaScriptで記述されたZend_ProgressBarUpdate関数に渡されます。このZend_ProgressBarUpdate関数が(4)進捗を表示します。実際には、Progressアクション内の処理が終了するまで(2)から(4)の処理は繰りかえされます。
それでは、それぞれの仕組がどのように実装されているか見てみましょう。
処理を開始と更新の受け取り
クライアント側から処理の開始を指示したり、進捗の更新を受け取るための場所としてiframeを利用します。このiframe内でProgressアクションのページを表示することで、Progressアクションを呼び出すとともに、Progressアクションの出力(つまり処理の進捗)を受け取る仕組になっています。
<!-- (1)iframeを表示しないための工夫 --> <style type="text/css"> #long-running-process { position: absolute; left: -100px; top: -100px; width: 1px; height: 1px; } ... </style> ... <!-- (2)iframe本体 --> <iframe src="<?php echo $this->url(array('controller' => 'index', 'action'=>'progress')) ?>" id="long-running-process"></iframe>
iframe本体は(2)の部分です。ここのsrc属性でiframeの中で表示されるページを指定しています。このページのURLはZend_ViewのURLビューヘルパを利用して生成していて、「IndexコントローラのProgressアクション」(実際には「/index/progress」)となっています。
(1)はiframeを表示しないための工夫で、iframeの位置をブラウザの描画外に指定しています。なお、iframeを表示しない方法として、他にCSSのdisplay: none;の利用も考えられますが、こちらは一部のブラウザでiframeの中身自体が読み込まれない問題が発生するので、利用しないでください。
次に、ここから呼び出されるProgressアクションを見ていきます。