Zend_Http_Clientのバグ?その3

投稿日: 2007年07月03月

前回

久しぶりにZend_Http_Client、というかPHPネタ。前回やってたことの続きなのでZend_Http_Clientのバージョンは古い。先日1.0が出たので修正されているかもしれない。

その1「cookieヘッダのセパレータがセミコロンだけのため、一部システムでうまくcookieが扱われない」

Zend_Http_Clientの例

Cookie: a=hoge;b=hoge2;c=hoge3

Firefox等の例

Cookie: a=hoge; b=hoge2; c=hoge3

のように出力される。一部のシステム、ぶっちゃけサイボウズではスペースがないと2個目以降のcookieが上手くわたってない模様。RFC的にどっちがどうなのかまでは調べてない。

対策としてはCookie.phpのZend_Http_Cookie::__toString()を変更。

変更前: return $this->name . '=' . urlencode($this->value) . ';';
変更後: return $this->name . '=' . urlencode($this->value) . '; ';

その2「GET/POSTパラメータに同一名の引数を渡すと勝手に[]がついてしまう」

こういうパラメータを渡したい場合。

a=1&a=2&a=3

HTMLでいうと、

<select name="a" multiple="multiple">
<option value="1">a</option>
<option value="2">a</option>
<option value="3">a</option>
</select>

これをGET/POSTしたとき、Zend_Http_Clientではこうなってしまう。

a%5B%5D=1&a%5B%5D=2&a%5B%5D=3

%5B%5Dってのはアンエスケープすると[]。つまりこうなる。

a[]=1&a[]=2&a[]=3

再現コードはこんな感じ。

$client = new Zend_Http_Client('http://example.com/hoge.php');
$param = array('a' => array('12', '14', '19'));
$client->setParameterPost($param);
$client->request(Zend_Http_Client::POST);

これじゃブラウザと動作が違っちゃうでしょ(゜Д゜)ゴルァ!!というお話。

原因はZend_Http_Client内部で使われてる標準関数(PHP5以降)のhttp_build_query()の動作がそうだから。

対策としてはZend_Http_Client::_buildHttpQuery()という関数をでっちあげて、http_build_query()の代わりにそっちを使うように変更。本来はZend_Http_Clientクラスを派生するなどすべき。

protected function _buildHttpQuery($formdata, $name = null)
{
    if(!is_array($formdata)){
        return '';
    }


    $query = array();

    foreach($formdata as $key => $value){
        if(is_null($name)){
            $tmp = urlencode($key) . '=';
        }else{
            $tmp = urlencode($name) . '=';
        }

        if(is_array($value)){
            $tmp = $this->_buildHttpQuery($value, $key);
        }else{
            $tmp .= urlencode($value);
        }


        array_push($query, $tmp);
    }


    return implode('&', $query);
}

修正したソースのバージョンはこれ

@version    $Id: Client.php 3834 2007-03-09 05:12:52Z bkarwin $
@version    $Id: Cookie.php 3834 2007-03-09 05:12:52Z bkarwin $

名前:宮内 はじめ

Code for Nagoya名誉代表

E2D3名古屋支部長

プログラマーです。GISやデータビズが好きです。このサイトは宮内の個人的なメモです。

プロフィール

お問い合わせ