HTTPでのやり取りを実装する中でContent-Typeについて調べたので、備忘録として残しておきます。
Content-Typeとは
Content-Type エンティティヘッダーは、リソースのメディア種別を示すために使用します。
要求においては (POST または PUT などで)、クライアントがサーバーにどのような種類のデータが実際に送られたかを伝えます。
構文例:
Content-Type: application/json;charset=utf8
Content-Type: application/x-www-form-urlencoded
Content-Type: text/html; charset=UTF-8
実際のリクエストはこんな感じになる。
POST /test HTTP/1.1
Host: xxx.xx.xx.x
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
field1=value1&field2=value2
GuzzleHttpを使ってPOSTする場合、Content-Typeに合わせたリクエスト送信オプション引数の設定が必要
Content-Typeがapplication/x-www-form-urlencoded
ならform_params
、
application/json
ならjson
をオプション引数に指定してあげる必要があります。
// form_paramsの場合
$client->request('POST', '/post', [
'form_params' => [
'foo' => 'bar',
'baz' => ['hi', 'there!']
]
]);
// jsonの場合
$client->request('PUT', '/put', [
'json' => [
'foo' => 'bar'
]
]);
Request Options - Guzzle Documentation
今時のPHP HTTPクライアントのGuzzleを使ってみた - Qiita
ここで正しいオプションを設定していないと、以下のようなエラーが出ます。(実際これが出て色々調べた)
Post request has been deprecated. Please use the "form_params" request option to send a application/x-www-form-urlencoded request, or the "multipart" request option to send a multipart/form-data request.
application/x-www-form-urlencoded
のレスポンスをPHPで解析
ついでにapplication/x-www-form-urlencoded
のレスポンスの解析方法(PHP)についても事例を記録しておきます。(jsonはjson_decodeするだけなので、ここでは省略します)
application/x-www-form-urlencodedでのレスポンスはURLエンコードされています。
まぁ、コンテンツタイプが「form」で「urlencoded」って書いてあるから、そりゃそうですね。
HTTPのPOSTメソッドでWebフォームの文字列を送信する場合に、文字列はエンコードして送信される。その際の符号化方法はMIMEのContent-Typeがapplication/x-www-form-urlencodedで指定される。この符号化方法をURLエンコードと言うことがある。
というわけで、標準関数のurldecodeでデコードすればいけます。
// レスポンス例
$response = 'error=0' . "\r\n"
. 'success=2' . "\r\n"
. 'resultCode=100000123450201200%2C40008408345320370200';
// URLデコード
$decode = urldecode($response);
// 改行ごとに配列化
$responseList = explode("\r\n", $decode);
var_dump($responseList);
// array(3) {
// [0] =>
// string(7) "error=0"
// [1] =>
// string(9) "success=2"
// [2] =>
// string(50) "resultCode=100000123450201200,40008408345320370200"
// }
$result = [];
foreach ($responseList as $row) {
// 各行ごとに"="で分割し、いい感じの配列にする。
$rowArray = explode("=", $row);
$result[$rowArray[0]] = $rowArray[1];
}
var_dump($result);
// array(3) {
// ["error"]=>
// string(1) "0"
// ["success"]=>
// string(1) "2"
// ["resultCode"]=>
// string(39) "100000123450201200,40008408345320370200"
// }