このすみろぐ

とあるWebエンジニアが、技術や趣味について書くブログです。

PHPのGuzzleで同名のGETクエリパラーメーターを送信する

仕事での話ですが、複数選択可能なパラメーターを送信するときに、配列形式のパラーメーター a[]=&a[]= でエラーとなる事象に遭遇しました。

原因はAPIが求めている複数選択パラメーターが、a=&a= という、同名パラーメーターを重ねて送信する方式だったからです。

PHPで普通に配列をGETクエリパラーメーター化すると、この方式が実現できません。 API側を変えることは難しい状況だったため、a=&a=で送る方法を調べました。

<?php

echo http_build_query(['a' => ['a', 'b', 'c']]) . "\n";
// a%5B0%5D=a&a%5B1%5D=b&a%5B2%5D=c

GuzzleHttp\Psr7\Queryを使う

改善策がなかなか発見できず苦労したのですが、結論から言うとStack Overflowの『How to set query parameters with same name as Guzzle?』を参考に実現できました。

stackoverflow.com

実際にGuzzleHttp\Psr7\QueryでGETクエリ用のパラメーターを作成すると、クエリ変換で同名パラメーターが作成されるとわかります。

<?php
// $ php composer.phar require guzzlehttp/psr7

require_once "vendor/autoload.php";

use GuzzleHttp\Psr7\Query;

echo Query::build(['a' => ['a', 'b', 'c']]) . "\n";
// a=a&a=b&a=c

配列パラーメーターの送り方は統一されていない

調査してわかったことですが、複数選択可能なパラメーターの送り方は、言語や文化によって異なるケースがあるようです。 私はずっと複数選択パラメーターを配列形式 a[]=&a[]= で送ると思い込んでいたので、そうでない方法があると知り、勉強になりました。

ser1zw.hatenablog.com

atmarkit.itmedia.co.jp

あとがき

GuzzleHttp\Psr7\Query を使えば良いのは判明したのですが、PHP標準のhttp_build_query()との動きの差分が気になります。

そのため、PSR-7のドキュメントを読んでいるのですが、今のところ、それらしい記述が見つかりません。 同名パラメーターは a=&a= で送る的な決まりごとが書いてありそうなのですが。

www.php-fig.org

a[]=&a[]=a=&a= のどちらがデファクトスタンダードか気になるので、もう少し調べてみたいと思います。