Zend_Http_Clientのすすめ
PHPでちょっとしたHTTPリクエストを送る必要がでてきた。
どうせGETだし単純だし file_get_contents() でいいやーと実装。
度重なる改修・機能追加,要件が膨らみ,
なにやら複雑なコードになってしまっていることは少なくない。
file_get_contents() はPHPのお手軽さの象徴のような関数だし,
加えてstream関数を駆使すればけっこうなんでもできてしまうのだけど
どう考えても複雑なことをするのに向いたインタフェイスではない。
そうなる可能性があるのなら初めから3rd partyのライブラリの利用を検討した方がいい。
一昔前はPEAR::HTTP_Requestがよく使われていたけど,PHP4互換コードなのでアレである。
PEAR::HTTP_Request2とやらはひそかにバージョンアップがなされているがどうなのやら。
で,個人的におすすめなのが Zend_Http_Client。
ZendFrameworkに含まれるライブラリだが,
frameworkは使わずともライブラリは単体で利用することができる。
いいところ
- PHP5(5.2ベース)なので,コードがきれい
- 設計もきれい
- PEARと違ってクラス名の衝突が起こりづらい(Zend_のprefixがある)
- 高機能(redirect追跡,backendはfsockopen/curl両対応,認証対応,Cookie対応...一通り揃っている)
- 日本語マニュアルもなかなか充実
悪いところ
- DRYになるようよく設計されているため,依存するZendFrameworkのライブラリが多い。全部を置くことができないなら自分で選別が必要になる。
- PHP5.2ベースのコードなので,namespaceがなくクラス名が長くなりがち
使い方は,ライブラリ群の親ディレクトリ(Zend)のひとつ上までinclude_pathを通しておいてrequireすればいい。
GETでリクエストして,HTTPステータスを取得,
proxy設定の例をざっくり書いてみた。
$zendBaseDir = dirname(__FILE__) . '/../../ZF/'; $includePath = get_include_path(); $includePath .= PATH_SEPARATOR . $zendBaseDir; set_include_path($includePath); require_once 'Zend/Http/Client.php'; $client = factory(); // 正常系 $uri = 'http://localhost/apiMock/http200.php'; $client->setUri($uri); $objRes = $client->request('GET'); var_dump($objRes->getStatus()); // 500 $uri = 'http://localhost/apiMock/http500.php'; $client->setUri($uri); $objRes = $client->request('GET'); var_dump($objRes->getStatus()); // timeoutは例外になる $uri = 'http://localhost/apiMock/slowResponse.php'; $client->setUri($uri); $client->setParameterGet('time', 5); try { $objRes = $client->request('GET'); } catch(Exception $e) { var_dump(get_class($e)); var_dump($e->getMessage()); } // 正常系 $client = factory_withProxy(); $uri = 'http://localhost/apiMock/http200.php'; $client->setUri($uri); try { $objRes = $client->request('GET'); } catch(Exception $e) { var_dump(get_class($e)); var_dump($e->getMessage()); } /** * @return Zend_Http_Client */ function factory() { $client = new Zend_Http_Client(); $client->setConfig(array( 'maxredirects' => 0, 'timeout' => 3) ); return $client; } /** * proxy設定をする場合 * @return Zend_Http_Client */ function factory_withProxy() { $config = array( 'adapter' => 'Zend_Http_Client_Adapter_Proxy', 'proxy_host' => 'localhost', 'proxy_port' => 8888, 'timeout' => 3, // 'proxy_user' => 'user', // 'proxy_pass' => 'pass', ); $client = new Zend_Http_Client(); $client->setConfig($config); return $client; }
上記のコードで必要になるライブラリ群は以下。
より高度な機能を使う場合はもっと増えるのだろう。
- Zend_Http_Client
- Zend_Loader
- Zend_Uri
- Zend_Http_Response
- Zend_Http_Response_Stream
- Zend_Uri_Http
- Zend_Validate_Abstract
- Zend_Validate_Ip
- Zend_Validate_Hostname
- Zend_Registry
- Zend_Http_Cient_Adapter_Socket
- Zend_Exception
- Zend_Http_Client_Exception
- Zend_Http_Cient_Adapter_Exception
- Zend_Http_Cient_Adapter_Proxy
それにしても私はZendFrameworkのライブラリの設計が好み。
惚れ惚れするドメイン分けだにゃ。