Help us understand the problem. What is going on with this article?

cURLでbody付きのGETリクエスト

More than 3 years have passed since last update.

お前は何を言ってるんだ?

------------------- ↓ 余談はここから ↓-------------------
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪


タイトルからミルコクロコップさんもビックリのことだが、
そういう依頼されたが来たというのだから小説より奇なりである。

body付きのHTTPリクエストならPOSTやPUTなどの話だと思うが、
仕様を見ると
・GETで送ってね
・クエリストリング駄目よ
(゚Д゚)ハァ?

つまり以下のコマンドが実現できればいいということか。

curl -X GET http://適当なURL/endpoint.php --data "{abc:efg}"

さて、これが困ったもので。
PHPでAPIの処理をするにはcURLライブラリを使うといろいろうまくいかなかったりする。
(検証部分は後書にコード付きで説明する)
あとchrome拡張とかのAPIツールとかはGET+BODYに対応してないのが多い。

(ー_ー;)。o O (どうしよう)

取りあえずcURL以外の方法でfile_get_contentsで実装。
stream_context_createを駆使すればUser-Agentを変えたりPOSTリクエストしたりと意外に柔軟にできるので実装は可能なものの、
エラー処理問題がどうしても発生して何とも言い難いものに。
(こちらも後書に記載)

それで丸く収めようと検証記事(この記事です)を書いている途中に面白いものを見つけた。
それが

CURLOPT_CUSTOMREQUEST

curlコマンドの-Xにあたるものだと理解しているが、
これを使えば行けそうだ。

------------------- ↓ 本題はここから ↓-------------------
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪


curlでGET+BODY

準備

まずは受信側の準備

endpoint.php
<?php
// method値の確認
echo "METHOD:".$_SERVER["REQUEST_METHOD"]."\n";
// body値の確認
// PHPでBODYの文字列を取るにはphp:://inputを取得する
echo "BODY:".file_get_contents('php://input')."\n";

curlコマンドで実行

$ curl http://適当なURL/endpoint.php --data "{abc:efg}"
METHOD:POST
BODY:{abc:efg}
$ curl -X GET http://適当なURL/endpoint.php --data "{abc:efg}"
METHOD:GET
BODY:{abc:efg}

問題なく動いているね。

CURLOPT_CUSTOMREQUESTで実装

コード

curl.php
$url = "http://適当なURL/endpoint.php";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);

curl_setopt($ch, CURLOPT_POSTFIELDS, '{abc:efg}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");

$res = curl_exec($ch);
curl_close($ch);
echo $res;

実行

$ php curl.php
METHOD:GET
BODY:{abc:efg}

(`・ω・´)

------------------- ↓ 後書はここから ↓-------------------
ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪


curlでGET+BODYを実現できるのか調査

cURLライブラリで検証

phpは5.6.11、cURLは7.43.0。

準備

まずは基本コード。
これ以降のコードは差し替えの部分だけ記述する。

curl.php
$url = "http://適当なURL/endpoint.php";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);

/*** ↓ 差し替え開始 ↓ ***/
/*** ↑ 差し替え終了 ↑ ***/

$res = curl_exec($ch);
curl_close($ch);
echo $res;

実行すると

$ php curl.php
METHOD:GET
BODY:

単純にCURLOPT_POSTFIELDSを設定

/*** ↓ 差し替え開始 ↓ ***/
curl_setopt($ch, CURLOPT_POSTFIELDS, '{abc:efg}');
/*** ↑ 差し替え終了 ↑ ***/

実行すると

$ php curl.php
METHOD:POST
BODY:{abc:efg}

BODYは取れたけど、POSTに変化している。

CURLOPT_POSTをfalseに設定

ではそのあとでPOSTをfalseに設定してみる

/*** ↓ 差し替え開始 ↓ ***/
curl_setopt($ch, CURLOPT_POSTFIELDS, '{abc:efg}');
curl_setopt($ch, CURLOPT_POST, false);
/*** ↑ 差し替え終了 ↑ ***/

実行すると

$ php curl.php
METHOD:GET
BODY:

(゚Д゚;) 一緒にBODYまで消えた!?
まさにPHPマジックだわ。

CURLOPT_HTTPGETを設定

POSTをfalseにする代わりに、
HTTPGETを使ってみる

/*** ↓ 差し替え開始 ↓ ***/
curl_setopt($ch, CURLOPT_POSTFIELDS, '{abc:efg}');
curl_setopt($ch, CURLOPT_HTTPGET, true);
/*** ↑ 差し替え終了 ↑ ***/

実行すると

$ php curl.php
METHOD:GET
BODY:

一緒デスタ。。。orz

file_get_contentsの場合

せっかくなのでこちらも載せておこう

stream_context_createを使ってGET+BODY

fget.php
$opts = array('http' =>
    array(
        'method'  => 'GET',
        'content' =>  '{abc:efg}',
    )
);

$context = stream_context_create($opts);
$res = @file_get_contents($url, false, $context);
echo $res;

まぁ、@からわかるようにあんまり推奨はしないけどね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした