[php][pear]HTTP_Request2のサンプル#5

Written by uechoco 1月 21
このエントリをはてなブックマークに追加[php][pear]HTTP_Request2のサンプル#5のはてなブックマーク被リンク数このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをBuzzurl(バザール)に追加

この記事は、HTTP_Requestのマニュアルに載っている全サンプルコードをHTTP_Request2対応で書き換えてみる企画の最終回(5回目)です。HTTP_Request2クラスの概要を知りたい方は、下記リンクの#1を参照ください。

全記事へのリンク:

#13 ダウンロード進捗バー(コマンドラインのみ)

php:
  1. <?php
  2. /**
  3.  * 例 48-13 ダウンロード進捗バー(コマンドラインのみ)
  4.  *
  5.  * @link http://pear.php.net/manual/ja/package.http.http-request.listeners.php
  6.  * @see  http://www.php.net/~helly/php/ext/spl/interfaceSplObserver.html
  7.  */
  8. require_once 'HTTP/Request2.php';
  9. require_once 'Console/ProgressBar.php';
  10.  
  11.  
  12. class HTTP_Request2_Observer_Progress implements SplObserver
  13. {
  14.     /**
  15.      * 対象となるファイルのハンドル
  16.      * @var int
  17.      */
  18.     protected $fp;
  19.  
  20.     /**
  21.      * インジケータの表示に使用する Console_ProgressBar のインスタンス
  22.      * @var Console_ProgressBar
  23.      */
  24.     protected $bar;
  25.  
  26.     /**
  27.      * 対象となるファイルの名前
  28.      * @var string
  29.      */
  30.     protected $target = "filename";
  31.  
  32.     /**
  33.      * 受信したファイルのバイト数
  34.      * @var int
  35.      */
  36.     protected $size;
  37.  
  38.     /**
  39.      * 対象となるファイルをオープンする
  40.      * @param string ファイル名
  41.      * @throws HTTP_Request2_Exception
  42.      */
  43.     function setTarget($target)
  44.     {
  45.         $this->target = $target;
  46.         $this->fp = @fopen($target, 'wb');
  47.         if (!$this->fp) {
  48.             throw new HTTP_Request2_Exception("'{$target}' をオープンできません");
  49.         }
  50.     }
  51.  
  52.     /**
  53.      * HTTP_Request2から呼ばれる (例えば、値が変わった時)
  54.      *
  55.      * @param SplSubject $subject
  56.      */
  57.     public function update(SplSubject $subject)
  58.     {
  59.         $event = $subject->getLastEvent();
  60.  
  61.         switch ($event['name']) {
  62.             case 'connect':
  63.                 $this->target = basename($subject->getUrl()->getPath());
  64.                 break;
  65.             case 'receivedHeaders':
  66.                 $headers = $event['data']->getHeader();
  67.                 if (isset($headers['content-disposition']) &&
  68.                     preg_match('/filename="([^"]+)"/', $headers['content-disposition'], $matches)) {
  69.                     $this->setTarget(basename($matches[1]));
  70.                 } else {
  71.                     $this->setTarget($this->target);
  72.                 }
  73.                 $this->bar = new Console_ProgressBar(
  74.                     '* ' . $this->target . ' %fraction% KB [%bar%] %percent%', '=>', '-',
  75.                     79, (isset($headers['content-length'])? round($headers['content-length'] / 1024): 100)
  76.                 );
  77.                 $this->size = 0;
  78.                 break;
  79.             case 'receivedEncodedBodyPart':
  80.             case 'receivedBodyPart':
  81.                 $this->size += strlen($event['data']);
  82.                 $this->bar->update(round($this->size / 1024));
  83.                 fwrite($this->fp, $event['data']);
  84.                 break;
  85.             case 'receivedBody':
  86.                 fclose($this->fp);
  87.                 break;
  88.         }
  89.     }
  90. }
  91.  
  92. try {
  93.     $req = new HTTP_Request2("http://pear.php.net/get/HTML_QuickForm-stable");
  94.  
  95.     $observer = new HTTP_Request2_Observer_Progress();
  96.     $req->attach($observer);
  97.  
  98.     $response = $req->send();
  99.  
  100. } catch (HTTP_Request2_Exception $e) {
  101.     die($e->getMessage());
  102. } catch (Exception $e) {
  103.     die($e->getMessage());
  104. }
  105.  
  106. /*****************************
  107.  * HTTP_Request_Listenerクラスを派生する代わりにSplObserverインターフェースを実装します。
  108.  *
  109.  * このとき、update(SplSubject $subject)メソッドを実装する必要があります。
  110.  * $subjectにはHTTP_Request2が代入されています(HTTP_Request2はSplSubjectの実装クラス)。
  111.  *
  112.  * たいていの場合、HTTP_Request2::getLastEvent()メソッドを呼び出して、イベントを取得します。
  113.  * 使用するアダプタによってはイベントを発生させないことがあります。
  114.  * 例えば、Mockアダプタはイベント発生させません。
  115.  *
  116.  * getLastEvent()メソッドの返り値はarray('name' => string, 'data' => mixed)の配列です。
  117.  * イベントは以下の8種類が用意されています。
  118.  *  - connect
  119.  *  - sentHeaders
  120.  *  - sentBodyPart
  121.  *  - receivedHeaders
  122.  *  - receivedBodyPart
  123.  *  - receivedEncodedBodyPart
  124.  *  - receivedBody
  125.  *  - disconnect
  126.  * イベントの種類によって、データの種類は異なります。
  127.  *****************************/
  128.  
  129. /*
  130.  
  131. // HTTP_Request でのリスナーの使用例です。これは、ファイルの
  132. // ダウンロードと保存を行うと同時に、処理の進捗状況をバーで表示します
  133. //
  134. // 注意すべき点は以下のとおりです
  135. // 1) ブラウザでなく、コンソールから実行しないといけません
  136. // 2) 出力バッファリングを OFF にしないと正常に動作しません
  137.  
  138. require_once 'HTTP/Request.php';
  139. require_once 'HTTP/Request/Listener.php';
  140. require_once 'Console/ProgressBar.php';
  141.  
  142. PEAR::setErrorHandling(PEAR_ERROR_DIE);
  143.  
  144. set_time_limit(0);
  145.  
  146. class HTTP_Request_DownloadListener extends HTTP_Request_Listener
  147. {
  148.     // 対象となるファイルのハンドル
  149.     // @var int
  150.     var $_fp;
  151.  
  152.     // インジケータの表示に使用する Console_ProgressBar のインスタンス
  153.     // @var object
  154.     var $_bar;
  155.  
  156.     // 対象となるファイルの名前
  157.     // @var string
  158.     var $_target;
  159.  
  160.     // 受信したファイルのバイト数
  161.     // @var int
  162.     var $_size = 0;
  163.  
  164.     function HTTP_Request_DownloadListener()
  165.     {
  166.         $this->HTTP_Request_Listener();
  167.     }
  168.  
  169.     // 対象となるファイルをオープンする
  170.     // @param string ファイル名
  171.     // @throws PEAR_Error
  172.     function setTarget($target)
  173.     {
  174.         $this->_target = $target;
  175.         $this->_fp = @fopen($target, 'wb');
  176.         if (!$this->_fp) {
  177.             PEAR::raiseError("'{$target}' をオープンできません");
  178.         }
  179.     }
  180.  
  181.     function update(&$subject, $event, $data = null)
  182.     {
  183.         switch ($event) {
  184.             case 'sentRequest':
  185.                 $this->_target = basename($subject->_url->path);
  186.                 break;
  187.  
  188.             case 'gotHeaders':
  189.                 if (isset($data['content-disposition']) &&
  190.                     preg_match('/filename="([^"]+)"/', $data['content-disposition'], $matches)) {
  191.  
  192.                     $this->setTarget(basename($matches[1]));
  193.                 } else {
  194.                     $this->setTarget($this->_target);
  195.                 }
  196.                 $this->_bar =& new Console_ProgressBar(
  197.                     '* ' . $this->_target . ' %fraction% KB [%bar%] %percent%', '=>', '-',
  198.                     79, (isset($data['content-length'])? round($data['content-length'] / 1024): 100)
  199.                 );
  200.                 $this->_size = 0;
  201.                 break;
  202.  
  203.             case 'tick':
  204.                 $this->_size += strlen($data);
  205.                 $this->_bar->update(round($this->_size / 1024));
  206.                 fwrite($this->_fp, $data);
  207.                 break;
  208.  
  209.             case 'gotBody':
  210.                 fclose($this->_fp);
  211.                 break;
  212.  
  213.             default:
  214.                 PEAR::raiseError("イベント '{$event}' が処理できません");
  215.         } // switch
  216.     }
  217. }
  218.  
  219. // 別のパッケージを使用してもかまいませんが、できるだけ大き目のものを
  220. // 選ばないと進捗バーが見えません
  221. $url = 'http://pear.php.net/get/HTML_QuickForm-stable';
  222.  
  223. $req =& new HTTP_Request($url);
  224.  
  225. $download =& new HTTP_Request_DownloadListener();
  226. $req->attach($download);
  227. $req->sendRequest(false);
  228. */
  229. ?>

最後のサンプルになりましたが、昔のHTTP_Request_Listenerに当たるSplObserver派生クラスのサンプルとなりました。HTTP_Request2のパッケージにはHTTP_Request2_Observer_Logが同梱されているので、そちらを参考にすると、SplObserver派生クラスについての理解が深められます。

全サンプルコードを載せましたが、0.2.0(alpha)の時点でだいたいの機能はそろっている気がしますね。

このエントリをはてなブックマークに追加[php][pear]HTTP_Request2のサンプル#5のはてなブックマーク被リンク数このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをBuzzurl(バザール)に追加

No Responses to “[php][pear]HTTP_Request2のサンプル#5”

コメントはまだありません。

Comments RSS rss うえちょこ@ぼろぐ TrackBack Identifier URI rss うえちょこ@ぼろぐ

コメントをどうぞ