GETやPOSTはよく使用するのですが、PUTやPATCHといったメソッドについてよくわからずにここまで来てしまいました。
調べてみると、メソッドの指定方法で値の伝わり方に差がありましたので、備忘録として残しておきます。
ここでいうメソッドとは、
curl [-X Method] URL [command]
の Method の部分です。
結論
結論から先に説明すると、Apache+PHP環境においては、
POSTパラメータを使うならPOSTメソッド
他のメソッドに意味はない
ということがわかりました。
実験方法
次の実験を行い、ローカル環境でそれぞれのメソッド通信を行い、結果がどのように変わるのか確認をしました。
前提
大前提として、それぞれの挙動を示しておきます。
GETメソッドを使ってデータを送信する
c:\ > curl -X GET http://192.168.254.128/cgi/method.php?name=get_data
$_SERVER['REQUEST_METHOD'] = "GET"
$_GET = array(1) { ["name"]=> string(8) "get_data"}
$_POST = array(0) {}
file_get_contents('php://input') = ""GETパラメータとして値がわたっていることがわかります。
POSTメソッドを使ってデータを送信する
c:\ > curl.exe -X POST http://192.168.254.128/cgi/method.php -d "name=post_data"
$_SERVER['REQUEST_METHOD'] = "POST"
$_GET = array(0) {}
$_POST = array(1) { ["name"]=> string(9) "post_data"}
file_get_contents('php://input') = "name=post_data"POSTパラメータとして値がわかっていることがわかります。
使用したPHPプログラム
<?php //method.php
$method = $_SERVER['REQUEST_METHOD'];
$get_all = $_GET;
$post_all = $_POST;
$content = file_get_contents('php://input');
// レスポンス
header("Content-Type: text/plain");
echo '$_SERVER[\'REQUEST_METHOD\'] = "' . $method . "\"\n";
echo '$_GET = ';
var_dump($get_all);
echo '$_POST = ';
var_dump($post_all);
echo 'file_get_contents(\'php://input\') = "' . $content . "\"\n";
?>ローカルVM(192.168.254.128)に配置し、閲覧実行権限を付与しています。
実験
Apacheを使ったサバクラシステムでは、一般的に使用されるメソッドが、
GET、POST、PATCH、PUT
の4種類ということでしたので、これらについて確認していきます。
①GETメソッドでPOSTパラメータを送信するとどうなるのか
c:\ > curl.exe -X GET http://192.168.254.128/cgi/method.php?name=get_data -d "name=post_data"
$_SERVER['REQUEST_METHOD'] = "GET"
$_GET = array(1) { ["name"]=> string(8) "get_data"}
$_POST = array(0) {}
file_get_contents('php://input') = "name=post_data"GETパラメータで送信した値は渡っていますが、POSTパラメータは渡っていないことがわかります。
つまりGETパラメータで値を送信すると、$_POSTで値を受け取ることができないということですね。
しかし、file_get_contentsを使うと、phpコンテンツとして値を取得することができることもわかりました。
②POSTメソッドでGETパラメータを送信するとどうなるのか
C:\ > curl.exe -X POST http://192.168.254.128/cgi/method.php?name=get_data -d "name=post_data"
$_SERVER['REQUEST_METHOD'] = "POST"
$_GET = array(1) { ["name"]=> string(8) "get_data"}
$_POST = array(1) { ["name"]=> string(9) "post_data"}
file_get_contents('php://input') = "name=post_data"POSTパラメータも、GETパラメータもサーバに渡っていることがわかります。
この動作から、POSTメソッドを使用した場合には、全てのパラメータがサーバに渡っていることがわかります。
③PUT、PATCHメソッドを使って各種パラメータを送信するとどうなるのか
c:\ > curl.exe -X PUT http://192.168.254.128/cgi/method.php?name=get_data -d "name=post_data"
$_SERVER['REQUEST_METHOD'] = "PUT"
$_GET = array(1) { ["name"]=> string(8) "get_data"}
$_POST = array(0) {}
file_get_contents('php://input') = "name=post_data"PUTメソッドを使用すると、GETパラメータは送られていますが、POSTパラメータは受け取ることができませんでした。
この結果はGETメソッドの時と同じ値が返ってきました。
PUTメソッドを使うとPOSTパラメータが受信できなくなるようです。
ここで、次のパラメータを使ったところ、思いもよらない結果が出ました。
C:\Users\keiai>curl.exe -X PUT http://192.168.254.128/cgi/method.php?name=get_data -dname
:
file_get_contents('php://input') = "name" file_get_contentsを使用すると、”-d”以降のデータを返す仕様となっているようですね。
間のスペースを無視するあたりがちょっとバグ気味な結果を返しています。
尚、PATCHメソッドについては、同じ挙動を取りましたので、割愛します。
④存在しないメソッドを使うとどうなるのか
とりあえず思いついた、HELLOメソッドでパラメータを送信してみました。
c:\ > curl.exe -X HELLO http://192.168.254.128/cgi/method.php?name=get_data -d "name=post_data"
$_SERVER['REQUEST_METHOD'] = "HELLO"
$_GET = array(1) { ["name"]=> string(8) "get_data"}
$_POST = array(0) {}
file_get_contents('php://input') = "name=post_data" 存在しないメソッドを使ったレスポンスは、GET、PUT、PATCHメソッドの時と同じ値でした。
この結果から、
POSTパラメータを使うときはPOSTメソッドを使用しなければいけない
他のメソッドは挙動が同じ
と特定しました。
⑤日本語メソッドも行けるか!?
やってみます。
C:\Users\keiai>curl.exe -X おはよう http://192.168.254.128/cgi/method.php
:
<title>400 Bad Request</title>
:
<h1>Bad Request</h1> 400番のエラーで叱られました。
さすがに日本語のメソッドは許してもらえませんね。
ちなみに、サーバのアクセスログを見ると、次のように出力されていました。
192.168.254.1 62562 80 - - [14/Dec/2025:16:17:11 +0900] "\xe3\x81\x8a\xe3\x81\xaf\xe3\x82\x88\xe3\x81\x86 /cgi/method.php HTTP/1.1" 400 483 "-" "-" HTMLエンコードされているので、
URLエンコード・デコード|日本語URLをサクッと変換 | すぐに使える便利なWEBツール | Tech-Unlimited
を使ってエンコードしたところ、ちゃんとエンコードできました。
192.168.254.1 62562 80 - - [14/Dec/2025:16:17:11 +0900] "おはよう /cgi/method.php HTTP/1.1" 400 483 "-" "-"Methodを使えば、普段言えないことも、サーバの管理者に伝えられるかもしれません。(やらないで)
⑥メソッドの限界と注意点
メソッドに何文字入るのか調べたところ、4000文字までは行けたのですが、6000文字あたりで叱られました。
Windowsのcurlの制限なのか、Server側の問題なのかはわかりませんが、かなりの文字数が入力できるので、HP上にメソッド名を表示できるサイトでは、
メソッド名を使ったインジェクション攻撃
対応をする必要もある気がしてきました。
今、私のサーバのアクセスログはとんでもない状態になっています。w
思ったこと
PUTやPATCHメソッドがどんなものか調べた結果を書こうと思っていたのですが、GETメソッドと同じ挙動をしていることがわかりがっかりしたので、メソッドに入れられる文字列等について調べました。
PUTやPATCHメソッドが特別なメソッドというわけではなく、リクエストの種類を明示しているだけという印象を受けました。
リクエストを受け取ったサーバ側で
PUTメソッドで送られている処理はこちら
といった分岐に使われるんだと思います。
メソッドの文字数制限、もっと厳しくてもいいのではないかと感じている今日この頃です。
