HTTP_Request_Listener

HTTP_Request_Listener --  HTTP_Request 操作にリスナーをアタッチする

HTTP_Request_Listener について

HTTP_Request_Listener は抽象クラスです。 これを継承すると、発生したイベントを受け取ってそれに対する応答を返すことができます。 HTTP_Request には、コンソールベースのプログレスバーのサンプルが含まれています。 これを実装するには、HTTP_Request_DownloadListener クラスを使用します。これは、 Console_ProgressBar パッケージを使用してダウンロードの進捗メーターを表示します。

HTTP_Request_Listener の使用例

リスナーを使用するには、確認したい特定の HTTP_Request あるいは HTTP_Response オブジェクトに対してリスナーをアタッチする必要があります。 アタッチするコードは、サンプルの一番最後にあります。 ごらんいただいてわかるとおり、HTTP_Request からその配下のすべての HTTP_Response オブジェクトに対してイベントリスナーが伝播します。 そして最初の HTTP_Request オブジェクトに対してのみアタッチが必要となります。

例 48-1HTTP_Request_Listener を使用したダウンロード進捗バー

<?php
/**
 * HTTP_Request でのリスナーの使用例です。これは、ファイルの
 * ダウンロードと保存を行うと同時に、処理の進捗状況をバーで表示します
 * 
 * 注意すべき点は以下のとおりです
 * 1) ブラウザでなく、コンソールから実行しないといけません
 * 2) 出力バッファリングを OFF にしないと正常に動作しません
 */

require_once 'HTTP/Request.php';
require_once 'HTTP/Request/Listener.php';
require_once 'Console/ProgressBar.php';

PEAR::setErrorHandling(PEAR_ERROR_DIE);

set_time_limit(0);

class HTTP_Request_DownloadListener extends HTTP_Request_Listener
{
   /**
    * 対象となるファイルのハンドル
    * @var int
    */
    var $_fp;

   /**
    * インジケータの表示に使用する Console_ProgressBar のインスタンス
    * @var object
    */
    var $_bar;

   /**
    * 対象となるファイルの名前
    * @var string
    */
    var $_target;

   /**
    * 受信したファイルのバイト数
    * @var int
    */
    var $_size = 0;

    function HTTP_Request_DownloadListener()
    {
        $this->HTTP_Request_Listener();
    }

   /**
    * 対象となるファイルをオープンする
    * @param string ファイル名
    * @throws PEAR_Error
    */
    function setTarget($target)
    {
        $this->_target = $target;
        $this->_fp = @fopen($target, 'wb');
        if (!$this->_fp) {
            PEAR::raiseError("'{$target}' をオープンできません");
        }
    }

    function update(&$subject, $event, $data = null)
    {
        switch ($event) {
            case 'sentRequest': 
                $this->_target = basename($subject->_url->path);
                break;

            case 'gotHeaders':
                if (isset($data['content-disposition']) &&
                    preg_match('/filename="([^"]+)"/', $data['content-disposition'], $matches)) {

                    $this->setTarget(basename($matches[1]));
                } else {
                    $this->setTarget($this->_target);
                }
                $this->_bar =& new Console_ProgressBar(
                    '* ' . $this->_target . ' %fraction% KB [%bar%] %percent%', '=>', '-', 
                    79, (isset($data['content-length'])? round($data['content-length'] / 1024): 100)
                );
                $this->_size = 0;
                break;

            case 'tick':
                $this->_size += strlen($data);
                $this->_bar->update(round($this->_size / 1024));
                fwrite($this->_fp, $data);
                break;

            case 'gotBody':
                fclose($this->_fp);
                break;

            default:
                PEAR::raiseError("イベント '{$event}' が処理できません");
        } // switch
    }
}

// 別のパッケージを使用してもかまいませんが、できるだけ大き目のものを
// 選ばないと進捗バーが見えません
$url = 'http://pear.php.net/get/HTML_QuickForm-stable';

$req =& new HTTP_Request($url);

$download =& new HTTP_Request_DownloadListener();
$req->attach($download);
$req->sendRequest(false);
?>

捕捉できるイベント

HTTP_Request クラスはこれらのイベントを送信します。

HTTP_Response クラスはこれらのイベントを送信します。