SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Zend Framework入門

プログレスバーを表示しよう - Zend_ProgressBar -

Zend Frameworkによる実践的なPHPアプリケーション開発 29

  • X ポスト
  • このエントリーをはてなブックマークに追加

Webアプリ用のアダプタ(プッシュ型)

 上で説明したZend_ProgressBar_Adapter_JsPushクラスは更新時(updateメソッドが呼ばれた時)と終了時(finishメソッドが呼ばれた時)にクライアントにデータを送信しますが、クライアント側のデータを処理するJavaScriptの関数は変更することができます。

Zend_ProgressBar_Adapter_JsPushクラスの主なメソッド
メソッド名 引数 説明
setUpdateMethodName $methodName 更新の通知を受け取るJavaScript側の関数を指定。デフォルトではZend_ProgressBar_Update
setFinishMethodName $methodName 処理終了の通知を受け取るJavaScript側の関数を指定。デフォルトではなし。

 特に、何も指定しない状態では終了を受け取る関数は指定されていないため、処理の終了時に何かしたい場合にはsetFinishMethodNameメソッドで指定する必要があります。

Webアプリ用のアダプタ(プル型)

 Zend_ProgressBar_Adapter_JsPullクラスもWebアプリ用のクラスです。こちらはプル型のサービスを作成するためのアダプタで、クライエントからのリクエストに対してJSON形式で進捗を送信するために利用します。

 プル型はプッシュ型と比べ、次のような違いがあります:

  • 送信するデータは純粋なJSON形式。
  • データにfinishedという項目が追加されており、値は更新時(updateメソッドやnextメソッド)にはfalseで終了時(finishメソッド)にはtrueに設定。
  • ディフォルトではデータを送信した後に、PHPの処理を終了。

 それでは、典型的なプル型の処理の流れを見ていきましょう:

  1. クライエントのJavaScriptなどが、リクエストをサーバに送信
  2. サーバで進捗の確認と、クライエントへの進捗の送信
  3. クライエントで進捗の表示

 ここではXMLHttpRequestを利用してリクエストの作成し、それをZend_ProgressBarが受けて処理するサンプルを見ていきましょう。このサンプルではフォーム内のボタンを押すたびに進捗が更新されるようになっています(なお、このサンプルはInternet Explorer 5以降で動作します)。

図5 プル型で進捗を更新するサンプル
図5 プル型で進捗を更新するサンプル

 まずはリクエストの作成です。

リスト8 リクエストの作成(pull.phtml)
<script type="text/javascript">
<!--
function get_progress() {
  //(1)リクエストオブジェクトの作成
  var http_obj = new ActiveXObject("Msxml2.XMLHTTP");
  //     結果を受け取った際の処理の登録
  http_obj.onreadystatechange = function() {
    if (http_obj.readyState == 4) {
       update(http_obj); //関数 update が最終的な処理を行う
    }
  };
  //(2)リクエストの実行
  http_obj.open("GET", "<?php echo $this->url(array('controller' => 'index',
                                  'action'=>'pullprogress',
                                  'session_name'=>'test1'))?>", true);
  http_obj.send(null);
}
...
<form>
 ...
 <!-- (3)クリックされたら更新 -->
 <input id="update" type="button" value="update progress" onClick="get_progress()">
</form>

 (3)にあるフォームのボタンがクリックされるとJavaScriptのget_progress関数が呼び出されます。このget_progress関数の中では、(1)リクエストのためのオブジェクトが準備され、(2)リクエストが実際に行われます。

 (1)では、リクエストの結果をupdate関数で処理することを登録しています。また、(2)ではリクエストを送信する先として「indexコントローラのpullprogressアクション」を指定しており、その際にパラメータとして「session_nameをtest1」を追加しています。

 このリクエストの処理を行うのが次のpullprogressアクションです。

リスト9 リクエストの処理(IndexController.php)
    public function pullprogressAction()
    {
        /* 必要なコンポーネントの読み込み */
        require_once('Zend/ProgressBar.php');
        require_once('Zend/ProgressBar/Adapter/JsPull.php');

	/* (4)セッション名を引数から取得 */
	$request = $this->getRequest();
	$session_name = $request->getUserParam('session_name');
	
        /* アダプタの作成 */
        $adapter = new Zend_ProgressBar_Adapter_JsPull();

        /* (5)本体の作成 */
        $progressbar = new Zend_ProgressBar($adapter, 0, 10,
					    $session_name);

	
	/* (6)next や update が呼ばれた後、ディフォルトでは
	   処理が終了する。もし、その後に処理を続けたい場合には
	   次のsetExitAfterFinishedメソッドを利用する。
        $progressbar->setExitAfterFinished(false);
	 */

        /* 本来はここで進捗の計算 */

        /* (7)進捗の更新や通知 */
        $progressbar->next();
    }

 プル型の場合は、リクエストが行われるたびにZend_ProgressBarオブジェクトが作成し直されます。そのため、どの処理の進捗を管理しているZend_ProgressBarオブジェクトを利用したいのかを、コントラクタで指定する必要があります。セッション名は(4)でパラメータから取得され、(5)でコンストラクタの第4引数として渡されています。

 通常のアプリケーションでは、その後に進捗が計算され(7)で更新と通知が行われます(この例では単純に進捗の値を1つ進めてその値を送信するnextメソッドが呼び出されています)。

 なお、プル型の場合、サーバでの処理は進捗を送信した時点で終わるため、next等のメソッドが呼び出されたら、そのままPHPのexit関数が呼び出されます。そのため、(7)以降でさらに処理を行いたい場合には(6)でコメントアウトされているsetExitAfterFinishedメソッドを利用して設定を変更してください。また、Zend FrameworkのMVC環境を利用している場合には、renderメソッドが呼び出されるのを抑止するためにviewRendererアクションヘルパーなどを利用する必要があります。

 (1)で設定したように、リクエストの結果をクライエント側で受け取るのはupdate関数です。

リスト10 更新の描画(pull.phtml)
function update(http_obj)
{
  //(8)JSON形式のデータの取り出し
  var data_text = http_obj.responseText;
  //(9)evalを使って変数dataに格納
  eval('var data =' + data_text + ';');
  // zend-progressbar-done を進捗状況に応じて伸ばす
  document.getElementById('zend-progressbar-done').style.width =
    data.percent + '%';
  document.getElementById('status').value =
    data.percent + "% " +
    data.current + "/" + data.max + " " +
    data.timeTaken +  "s elapsed (" +
    data.timeRemaining + "s remaining)" +
    data.finished;
}

 このupdate関数はリクエストオブジェクトを受け取り、(8)でその中にあるJSON形式のデータをテキストとして取り出します。そして(9)でJavaScriptのeval関数を利用して、データをdata変数に格納しています。

おわりに

 今回は処理の進捗を表示するためのモジュール、Zend_ProgressBarを紹介しました。コンソールアプリから利用する場合はもちろん、今回紹介したパターンを利用すれば、Webアプリにプログレスバーを埋め込むことも簡単にできると思います。

 次回はZend_Controllerモジュールまわりの処理が、最近どのように変わってきたかについての解説を行う予定です。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Zend Framework入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 風田 伸之(カゼタ ノブユキ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5464 2010/10/14 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング