GuzzleはPHPのHTTPライブラリです。何とでもデータのストリーミングが可能だったりと、抽象的な設計でありながらも、簡単なことをしたいときは簡単に見えるインターフェースでもあり、とても使いやすくて便利です。
use Guzzle\Http\Client as GuzzleClient;
$client = new GuzzleClient('http://example.com');
$params = array(
'p' => '123',
'ps' => array('abc', 'def', 'ghi')
);
$request = $client->post('/action.php', null, $params);
$response = $request->send();
if ($response->getStatusCode() == 200) {
// 成功
} else {
// 失敗
}
PHPではクエリ文字列で配列を渡したいとき、配列みたいに書きますね。Guzzleではデフォルトでそれを再現してくれます。パラメータに配列を含んでいる上のコードは、以下のボディをPOSTします。
p=123&ps[0]=abc&ps[1]=def&ps[2]=ghi
これをPHPで受け取るとこのとおり。
var_dump($_POST['ps']);
/*
array(3) {
[0] =>
string(3) "abc"
[1] =>
string(3) "def"
[2] =>
string(3) "ghi"
}
*/
ところが、HTTPの通信相手がPHPとは限りません。PHPでない場合、重複キーありありの場合もあります。
p=123&ps=abc&ps=def&ps=ghi
この形式でクエリ文字列を作りたい場合、クエリ文字列コレクションオブジェクト Guzzle\Http\QueryString
のパラメータ収集に、Guzzle\Http\QueryAggregator\DuplicateAggregator
を使います。実はパラメータ収集の動作は PhpAggregator
オブジェクトがデフォルトだというだけで、簡単に交換可能になっているのです。
まず、GETパラメータの場合は簡単です。クエリ部が QueryString
オブジェクトなのでこのとおり。
$request->getQuery()->setAggregator(
new \Guzzle\Http\QueryAggregator\DuplicateAggregator()
);
POSTパラメータの場合が少し厄介で、インターフェースだけ見ていると設定箇所が見えないところに隠れています。post()
メソッドは Guzzle\Http\Message\RequestInterface
を返しますが、それはGETと共通のインターフェースであって、ボディを持つPOSTのようなリクエストでは、その正体が Guzzle\Http\Message\EntityEnclosingRequest
となります。そこに、ボディ用の QueryString
を得る getPostFields()
が隠れています。
/* @var $request \Guzzle\Http\Message\EntityEnclosingRequest */
$request = $client->post('/action.php', null, $params);
$request->getPostFields()->setAggregator(
new \Guzzle\Http\QueryAggregator\DuplicateAggregator()
);
はいこれで、リクエストボディを文字列操作で作って渡すなんてする必要ありませんね。
他にも、CommaAggregator
なんてのもありました。値をカンマでつないでキー重複を避けるみたいです。QueryAggregatorInterface
はわりと簡単なインターフェースなので、自分用の配列対応を書くこともできます。