PHP 入力ストリーム php://input はじめに 再版
PHP 入力ストリーム php://input
xml-rpc を使用する場合、サーバー側は、$_POST 配列ではなく、主に PHP 入力ストリーム input を通じてクライアント データを取得します。したがって、ここでは主に php 入力ストリーム php://input
php://input の概要について説明します。公式の PHP マニュアル文書には、明確に概要が説明されている段落があります。
「php://input を使用すると、生の POST データを読み取ることができます。$HTTP_RAW_POST_DATA に代わるメモリ消費量が少なく、特別な php.ini ディレクティブは必要ありません。php://input は使用できません。 enctype="multipart/form-data".
翻訳すると、
"php://input は未処理の POST データを読み取ることができます。 $HTTP_RAW_POST_DATA と比較して、メモリへの負担が少なく、特別な php.ini 設定は必要ありません。 enctype=multipart/form-data には php://input は使用できません。
この概要を 3 つの部分に分けて段階的に理解していきます。 POST データの読み取り
multipart/form-data タイプには使用できません
php://input VS $HTTP_RAW_POST_DATA
POST データの読み取り
PHP を使用する場合は、組み込み変数 $_POST $ に精通している必要があります。 _POST と php://input の関係と違いは何ですか? また、php://input は PHP 入力ストリームであるため、クライアントがサーバーと対話する最も一般的なメソッドは GET です。
これは、テストと観察から要約するのに非常に効果的な方法であることがわかります。
@file 192.168.0.6:/phpinput_server.php は、受信したデータを出力します。
@file 192.168.0.8:/phpinput_post.php は、POST を使用したフォーム データの送信をシミュレートします。 Method
@file 192.168.0.8:/phpinput_xmlrpc.php は、POST メソッドを使用して xmlrpc リクエストの発行をシミュレートします。
@file 192.168.0.8:/phpinput_get.php は、GET メソッド phpinput_server.php および phpinput_post.php を使用してフォーム番号の送信をシミュレートします。 🎜 >
//@file phpinput_server.php
$raw_post_data = file_get_contents('php://input', 'r');
echo "-- - ----$_POST----n";
echo var_dump($_POST) . "n";
echo "--- - ---php://input-------------n";
echo $raw_post_data . "n";
?>
< ? php
//@file phpinput_post.php
$http_entity_body = 'n=' . urldecode('7788');
$http_entity_type = ' application/x-www-form-urlencoded';
$http_entity_length = strlen($http_entity_body);
$host = '192.168.0.6';
$port = 80;
$path = ' /phpinput_server.php';
$fp = fsockopen($host, $port, $error_no, $error_desc, 30);
if ($fp) {
fputs($fp, "POST { $ path} HTTP/1.1rn");
fputs($fp, "ホスト: {$host}rn");
fputs($fp, "Content-Type: {$http_entity_type}rn");
fputs($fp, "Content-Length: {$http_entity_length}rn");
fputs($fp, "接続: closenrn");
fputs($fp, $http_entity_body . "rnrn" ) ;
while (!feof($fp)) {
$d .= fgets($fp, 4096);
}
fclose($fp);
echo $ d;
}
?>
ngrep ツールを使用して http リクエスト パケットを取得できます (検出する必要があるのは php://input であるため、 http ここでデータ パケットをリクエストします)。テスト スクリプト phpinput_post.php を実行してみましょう
@php /phpinput_post.phpHTTP/1.1 200 OK
Date: Thu, 08 Apr 2010 03:23:36 GMT
Server: Apache/2.2.3 (CentOS)
X-Powered-By: PHP/5.1.6
Content-Length: 160
Connection: close
Content-Type: text/html
; -------$_POST------
array(2) {
["n"]=> string(9) "perfgeeks"
["p"]=> string(4) "7788"
}
----------php://input---------- ---
n=perfgeeks&p=7788 ngrep を通じてキャプチャされた http リクエスト パケットは次のとおりです:
T 192.168.0.8:57846 -> 192.168.0.6:80 [AP]
POST / phpinput_server .php HTTP/1.1..
ホスト: 192.168.0.6..Content-Type: application/x-www-form-urlencoded..Co
ntent-Length: 18..Connection: close... n=perfgeeks&p=7788.... よく見ると、http 内の
1、$_POST データ、php://input データ、および httpd エンティティ本体データが「一貫している」
2 であることが簡単にわかります。 request Content-Type は application/x-www-form-urlencoded で、HTTP リクエスト本文のデータが HTTP post メソッドを使用して送信されたフォーム データであり、urlencode() によって処理されたことを示します。
(注: 以下ではプロンプトが表示されない太字の部分に注意してください) http://www.k686.com
スクリプト phpinput_xmlrpc の元のファイルの内容を見てみましょう。 php。POST メソッドによって送信された xml-rpc リクエストをシミュレートします。
//@file phpinput_xmlrpc.php
$http_entity_body = "nn jt_userinfo";
$http_entity_type = 'text/html';
$ http_entity_length = strlen($http_entity_body);
$host = '192.168.0.6';
$port = 80;
$path = '/phpinput_server.php';
$fp = fsockopen($host, $port, $error_no, $error_desc, 30);
if ($fp) {
fputs($fp, "POST {$path} HTTP/1.1rn");
fputs($fp, "ホスト: {$host}rn");
fputs($fp, "Content-Type: {$http_entity_type}rn ");
fputs($fp, "Content-Length: {$http_entity_length}rn");
fputs($fp, "接続: closenrn");
fputs($fp, $http_entity_body . "rnrn");
while (!feof($fp)) {
$d .= fgets($fp, 4096);
}
fclose($fp);
echo $d;
}
?>
同样地,让我们来执行这个测试 脚本
@php /phpinput_xmlrcp.phpHTTP/1.1 200 OK
日付: 木、08 4月 2010 03:47:18 GMT
サーバー: Apache/2.2.3 (CentOS)
X-Powered-By: PHP/5.1.6
コンテンツの長さ: 154
接続: 閉じる
コンテンツ タイプ: text/html; charset=UTF-8
------$_POST------
array(0) {
}
------php://input-------------
< methodcall>
この脚本を実行するとき、我们通ngrep抓取的http请要求データ包如下
T 192.168.0.8: 45570 -> 192.168.0.6:80 [AP]
POST /phpinput_server.php HTTP/1.1..
ホスト: 192.168.0.6..Content-Type: text/html..Content-Length: 75..Connect
tion: 閉じる.....
/name>.
1、http 要求内の Content-Type は text/xml です。これは、http 要求の本文データが xml データ形式であることを示しています。
2、サービス エンド $_POST が出力されるのは空数の集合であり、http エンティティ本文とは一致しません。 -Type は、application/x-www-form-urlencoded
3 ではなく text/xml ですが、php://input データも、http エンティティ本体データと一致します。つまり、php://inputdatabase と $_POSTdatabase
私は GET メソッド経由で表データを交換する場合、php://input は GET メソッドの表データを取得できませんか? ここで、私は phpinput_server.php 文を追加しました。
//@file phpinput_server.php
$raw_post_data = file_get_contents('php://input', 'r ');
echo "------$_GET------n";
echo var_dump($_GET) 。 "n";
echo "------php://input-------------n";
echo $raw_post_data 。 "n";
?>
//@file phpinput_get.php
$query_path = 'n=' 。 urldecode('perfgeeks') 。 '&p=' 。 urldecode('7788');
$host = '192.168.0.6';
$port = 80;
$path = '/phpinput_server.php';
$d = '';
$fp = fsockopen($host, $port, $error_no, $error_desc, 30);
if ($fp) {
fputs($fp, "GET {$path}?{$query_path} HTTP/1.1rn");
fputs($fp, "ホスト: {$host}rn");
fputs($fp, "接続: closenrn");
while (! feof($fp)) {
$d .= fgets($fp, 4096);
}
fclose($fp);
echo $d;
}
? >
同様に、私は以下の phpinput_get.php 検査スクリプトを実行し、通常の場合の GET メソッド提交表データを模倣しました。
@php /phpinput_get.phpHTTP/1.1 200 OK
日付: 木、2010 年 4 月 8 日 07:38:15 GMT
サーバー: Apache/2.2.3 (CentOS)
X-Powered-By: PHP/5.1.6
コンテンツの長さ: 141
接続: 閉じる
コンテンツ タイプ: text/html; charset=UTF-8
------$_GET------
array(2) {
[ "n"]=>
string(9) "perfgeeks"
["p"]=>
string(4) "7788"
}
-- -----php://input---------------この時点では、ngrepTool を使用し、捕捉された関連する http请要求データパケット包如下
T 192.168.0.8 :36775 -> 192.168.0.6:80 [AP]
GET /phpinput_server.php?n=perfgeeks&p=7788 HTTP/1.1..
ホスト: 192.168.0.6..接続: close....比较POST メソッド提交httpただし、ハードデータ http エンティティ ボディの場合は、Content-Type と Content-Length が正しく指定されます。 php://input は、$_GET データではなく、http エンティティ本体データを取得することもできます。値が application/x-www-form-urlencoded の場合、php は http requestbody に関連するデータを $_POST という数値集合に挿入し、$_POST 数値集合内にあるデータは urldecode() 解析の結果となります。除该Content-Type,他有multipart/form-data表示データデータは表单データ,稍後我们介绍)
2. Content-Type が multipart/form-data でない限り、php://input data (この条件は後で紹介します)。 php://input データは、データの http エンティティ本体部分と一致します。この部分的に一貫したデータの長さは、Content-Length によって指定されます。
3. Content-Type が application/x-www-form-urlencoded で、送信メソッドが POST メソッドの場合にのみ、$_POST データと php://input データが「一致」します (引用符付き)。形式を示します)一貫性がなく、一貫した内容)。そうでなければ、それらは矛盾します。
4、php://input は $_GET データを読み取ることができません。これは、http リクエストのボディ部分ではなく、http リクエスト ヘッダー (header) の PATH フィールドに $_GET データが query_path として書き込まれているためです。
これは、xml_rpc サーバーが file_get_contents(‘php://input’, ‘r’) を通じてデータを読み取る理由を理解するのにも役立ちます。 $_POST から読み取るのではなく、xml_rpc のデータ仕様が xml であり、その Content-Type が text/xml であるためです。
php://input は multipart/form-data と遭遇します
ファイルをアップロードするとき、フォームは次のように記述されます