Zend_ProgressBar(日本語)

導入

Zend_ProgressBar は、 さまざまな環境上でプログレスバーの作成や更新を行うコンポーネントです。 単一のバックエンドが、複数のアダプタの中のいずれかを用いて進捗状況を出力します。 更新のたびに現在値とオプションのメッセージを受け取り、 進捗率や残り時間などを計算してアダプタを呼び出します。

Zend_Progressbar の基本的な使用法

Zend_ProgressBar の使い方はきわめて簡単です。 単純に Zend_Progressbar の新しいインスタンスを作成し、 最小値と最大値を指定した上でデータ出力用のアダプタを選択するだけです。 何かのファイルの処理を行いたい場合は、たとえば次のようになります。

$progressBar = new Zend_ProgressBar($adapter, 0, $fileSize);

while (!feof($fp)) {
    // なにかの処理

    $progressBar->update($currentByteCount);
}

$progressBar->finish();

まず第一段階として、 Zend_ProgressBar のインスタンスを作成してアダプタを指定し、 最小値を 0、最大値をファイルのサイズに指定します。 ループ内でファイルが処理されるたびに、 現在のバイト数でプログレスバーを更新します。 ループを抜けた後で、プログレスバーを処理完了状態に設定します。

Zend_ProgressBarupdate() メソッドを引数なしでコールすることもできます。 その場合は、単に残り時間を再計算してアダプタに通知します。 これは、データが何も更新されていないけれども プログレスバーを更新したいという場合に有用です。

進捗の永続化

複数のリクエストにまたがってプログレスバーを持続させたい場合は、 コンストラクタの 4 番目の引数でセッション名前空間名を指定します。 そうすると、プログレスバーのコンストラクタ内ではアダプタへの通知が行われず update() あるいは finish() をコールしたときにのみ通知が行われるようになります。 また、現在の値や状況表示用テキスト、 そして残り時間計算用の開始時刻などは次のリクエストにも引き継がれるようになります。

標準のアダプタ

Zend_ProgressBar には次の 3 つのアダプタが同梱されています。

Zend_ProgressBar_Adapter_Console(日本語)

Zend_ProgressBar_Adapter_Console は、 ターミナル用に使用するテキストベースのアダプタです。 ターミナルの横幅を自動的に検出できますが、 独自に幅を指定することもできます。 プログレスバーとともに表示する要素や、その順序も変更できます。 また、プログレスバーそのものの形式も設定できます。

自動的なコンソール幅の認識

この機能を *nix 系のシステムで使用するには shell_exec が必要です。Windows ではターミナルの幅は 80 文字固定なので、 認識処理は不要です。

アダプタのオプションを設定するには、set* メソッドを使用するか、あるいはコンストラクタの最初のパラメータで 配列か Zend_Config インスタンスを渡します。 使用できるオプションは次のとおりです。

  • outputStream: さまざまな出力ストリーム。 STDOUT 意外に出力したい場合に使用します。 php://stderr のようなストリーム、 あるいはファイルへのパスを指定できます。

  • width: 整数値、あるいは Zend_Console_ProgressBar の定数 AUTO

  • elements: デフォルトは NULL。 あるいは以下の Zend_Console_ProgressBar の定数のうちの少なくともひとつを値として持つ配列。

    • ELEMENT_PERCENT: パーセントであらわした現在値。

    • ELEMENT_BAR: パーセンテージを表示するバー。

    • ELEMENT_ETA: 自動的に計算した予想残り時間。 この要素が表示されるのは、開始後 5 秒たってからです。 それまでは正確な結果を算出できないからです。

    • ELEMENT_TEXT: 現在の処理に関する状況を説明するオプションのメッセージ。

  • textWidth: ELEMENT_TEXT 要素の幅を文字数で表したもの。デフォルトは 20。

  • charset: ELEMENT_TEXT 要素の文字セット。デフォルトは utf-8。

  • barLeftChar: プログレスバー内で左側のインジケータとして使用する文字列。

  • barRightChar: プログレスバー内で右側のインジケータとして使用する文字列。

  • barIndicatorChar: プログレスバー内でインジケータとして使用する文字列。 これは空にすることもできます。

Zend_ProgressBar_Adapter_JsPush(日本語)

Zend_ProgressBar_Adapter_JsPush は、 ブラウザ内のプログレスバーを Javascript の Push で更新するアダプタです。 つまり、実行中のプロセスの情報を取得するために改めて接続を行う必要がなく、 そのプロセス自身が状況を直接ブラウザに送信するということです。

アダプタのオプションを設定するには、set* メソッドを使用するか、あるいはコンストラクタの最初のパラメータで 配列か Zend_Config インスタンスを渡します。 使用できるオプションは次のとおりです。

  • updateMethodName: 毎回の更新時にコールされる javascript のメソッド。 デフォルト値は Zend_ProgressBar_Update です。

  • finishMethodName: 状態を設定した後にコールされる javascript のメソッド。 デフォルト値は NULL で、この場合は何も行われません。

このアダプタの使い方はきわめて単純です。まず、ブラウザ上にプログレスバーを作成します。 これは JavaScript を用いたものでもかまいませんしプレーンな HTML によるものでもかまいません。それから、更新時のメソッドと 終了時のメソッド (オプション) を JavaScript で定義します。 これらのメソッドは、どちらも唯一の引数として json オブジェクトを受け取るようにします。 そして、処理時間が長くかかるウェブページを iframe タグあるいは object タグの中で呼び出します。処理の実行中に、 更新が行われるたびにアダプタのメソッドがコールされます。 引数として渡される json オブジェクトには次のパラメータが含まれています。

  • current: 現在の値。

  • max: 最大値。

  • percent: 算出したパーセンテージ。

  • timeTaken: これまでの経過時間。

  • timeRemaining: プロセスが終了するまでの予想残り時間。

  • text: オプションのメッセージ (指定した場合のみ)。

例660 クライアント側の基本例

この例では、JsPush アダプタ用の HTML および CSS、JavaScript の基本的な設定方法を示します。

<div id="zend-progressbar-container">
    <div id="zend-progressbar-done"></div>
</div>

<iframe src="long-running-process.php" id="long-running-process"></iframe>
#long-running-process {
    position: absolute;
    left: -100px;
    top: -100px;

    width: 1px;
    height: 1px;
}

#zend-progressbar-container {
    width: 100px;
    height: 30px;

    border: 1px solid #000000;
    background-color: #ffffff;
}

#zend-progressbar-done {
    width: 0;
    height: 30px;

    background-color: #000000;
}
function Zend_ProgressBar_Update(data)
{
    document.getElementById('zend-progressbar-done').style.width =
         data.percent + '%';
}

これは、黒の枠線と進捗状況表示用ブロックからなるシンプルなコンテナを作成します。 iframeobjectdisplay: none; で隠してしまってはいけません。Safari 2 などでは、 そうすると実際のコンテンツを読み込まなくなってしまします。

プログレスバーを自作するのではなく、Dojo や jQuery などの既存の JavaScript ライブラリのものを利用したいこともあるでしょう。 たとえば次のようなものがあります。


更新間隔

あまり頻繁に更新しすぎないようにしましょう。 毎回の更新は、少なくとも 1kb の大きさとなるからです。 これは、Safari が実際にレンダリングを行って関数をコールするのに必要なサイズです。 Internet Explorer の場合はこれは 256 バイトとなります。

Zend_ProgressBar_Adapter_JsPull(日本語)

Zend_ProgressBar_Adapter_JsPull は jsPush とは逆の動作をします。つまり、 更新をブラウザにプッシュするのではなく更新情報をほかから受け取ることになります。 一般に、このアダプタを使う場合は Zend_ProgressBar の persistence オプションを使用する必要があります。 通知を受け取ると、このアダプタは JSON 文字列をブラウザに送ります。 その内容は jsPush アダプタから送られてくるものとほぼ同じです。 唯一の違いは、追加のパラメータ finished が含まれることです。このパラメータは、 update() がコールされた場合は FALSEfinish() がコールされた場合は TRUE となります。

アダプタのオプションを設定するには、set* メソッドを使用するか、あるいはコンストラクタの最初のパラメータで 配列か Zend_Config インスタンスを渡します。 使用できるオプションは次のとおりです。

  • exitAfterSend: データがブラウザに送信された後に、 現在のリクエストを終了します。デフォルトは TRUE です。