LoginSignup
21
21

More than 5 years have passed since last update.

GuzzleでPHP式配列じゃないクエリ文字列のPOST

Posted at

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 はわりと簡単なインターフェースなので、自分用の配列対応を書くこともできます。

21
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
21