36
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-03-04

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

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


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

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;

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

36
30
3

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
36
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?