それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Guzzle で name[]=1 のような添字なしのリクエストを組み立てる。

Guzzle さんは、内部的に http_build_query を使っている。

そのため、次のようなリクエストのパラメタを渡すと。

$gz->request('GET' , [ 'name'=>['a','b','c']] )

次のようなリクエストを作り出す。

?name[0]=a&name[1]=b&name[2]=c

これは、あらゆるHTTPサーバーが配列として解釈してくれるかといと、全然ダメ。

サーバーのよっては次のようなリクエストを欲しがる場合がある。

?name[]=a&name[]=b&name[]=c

また、サーバーによっては、チェックボックスを使ったフォームのようなHTTPリクエストを欲しがる場合もある。

?name=a&name=b&name=c

どうするのか。

結論 置換する。

あれこれ模索したが、単純に置換するのが早い。

<?php
// 配列が name[0]=value になるのを避けて、name[]=value にする
$str = http_build_query( $data, $numeric_prefix=false, $arg_separator = null, $encoding_type );
$str = preg_replace( '/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $str );
$cli->request('GET', ['query'=>$str],$options );

POSTの場合はどうするのか

POSTの場合も同じである。

$cli->request('POST', ['form_data'=>$str],$options );

Guzzleに渡す配列のキーが異なる。HTTPリクエストのボディに入れるのか、クエリ文字列にするのか、この違いだけで使う文字列とエンコーディングは同じである。(application/x-www-form-urlencoded )

このような問題があるのでHTTPリクエストで配列を渡す仕様はとても不安定になりやすい。

この問題は、エンコーディングapplication/JSON が選ばれている理由でもあるのだろうと思います。

クエリ文字列やform-urlencoded (ボディ)でリクエストに配列を送信するのは、枯れてているHTTPリクエストにおいて解決しない問題ですよね。

参考資料

https://github.com/guzzle/guzzle/issues/2252