PHP
リクエストデータの読み込み
サーチ…
備考
GETとPOSTの選択
GETリクエストは、ページのレンダリングに必要なデータを提供するのに最適で、複数回(検索クエリ、データフィルタなど)使用することができます。それらはURLの一部です。つまり、ブックマークして再利用することができます。
一方、 POST要求はサーバーにデータを1回だけ送信するためのものです(連絡フォーム、ログインフォームなど)。 ASCIIのみを受け付けるGETとは異なり、POSTリクエストはファイルアップロードを含むバイナリデータも許可します 。
データの脆弱性を要求する
検証を行わずに$ _GETおよび$ _POSTスーパーグローバルからデータを取得することは悪い習慣とみなされ、ユーザーが潜在的にコードまたはSQLインジェクションを介してデータにアクセスしたり侵害したりする方法を開きます 。無効なデータは、そのような攻撃を防ぐためにチェックされ、拒否されるべきです。
リクエストデータは、 こことここで説明したように、コードでどのように使用されているかによってエスケープする必要があります 。 この答えには、一般的なデータ使用の場合のいくつかの異なるエスケープ関数があります 。
ファイルアップロードエラーの処理
$_FILES["FILE_NAME"]['error']
(ここで"FILE_NAME"
はファイル入力の名前属性の値で、フォームに存在します)は次のいずれかの値を含んでいます:
-
UPLOAD_ERR_OK
- エラーはなく、ファイルはUPLOAD_ERR_OK
アップロードされました。 -
UPLOAD_ERR_INI_SIZE
- アップロードされたファイルがphp.ini
upload_max_filesizeディレクティブを超えています。 -
UPLOAD_ERR_PARTIAL
- アップロードされたファイルが、HTML形式で指定されたMAX_FILE_SIZE指令を超えています。 -
UPLOAD_ERR_NO_FILE
- アップロードされたファイルがありません。 -
UPLOAD_ERR_NO_TMP_DIR
- 一時フォルダがありません。 (PHP 5.0.3より) -
UPLOAD_ERR_CANT_WRITE
- ファイルをディスクに書き込めませんでした。 (PHP 5.1.0以降)。 -
UPLOAD_ERR_EXTENSION
- PHP拡張UPLOAD_ERR_EXTENSION
がファイルのアップロードを停止しました。 (PHP 5.2.0以降)。
エラーをチェックする基本的な方法は次のとおりです。
<?php
$fileError = $_FILES["FILE_NAME"]["error"]; // where FILE_NAME is the name attribute of the file input in your form
switch($fileError) {
case UPLOAD_ERR_INI_SIZE:
// Exceeds max size in php.ini
break;
case UPLOAD_ERR_PARTIAL:
// Exceeds max size in html form
break;
case UPLOAD_ERR_NO_FILE:
// No file was uploaded
break;
case UPLOAD_ERR_NO_TMP_DIR:
// No /tmp dir to write to
break;
case UPLOAD_ERR_CANT_WRITE:
// Error writing to disk
break;
default:
// No error was faced! Phew!
break;
}
POSTデータの読み込み
POSTリクエストからのデータは、連想配列の形式でスーパーグローバル $_POST
に格納されます。
存在しない配列項目にアクセスすると通知が生成されるので、 isset()
またはempty()
関数、またはヌル結合演算子を使用して常に存在を確認する必要があります。
例:
$from = isset($_POST["name"]) ? $_POST["name"] : "NO NAME";
$message = isset($_POST["message"]) ? $_POST["message"] : "NO MESSAGE";
echo "Message from $from: $message";
$from = $_POST["name"] ?? "NO NAME";
$message = $_POST["message"] ?? "NO MESSAGE";
echo "Message from $from: $message";
GETデータを読む
GET要求からのデータは、連想配列の形式でスーパーグローバル $_GET
に格納されます。
存在しない配列項目にアクセスすると通知が生成されるので、 isset()
またはempty()
関数、またはヌル結合演算子を使用して常に存在を確認する必要があります。
例:(URL /topics.php?author=alice&topic=php
)
$author = isset($_GET["author"]) ? $_GET["author"] : "NO AUTHOR";
$topic = isset($_GET["topic"]) ? $_GET["topic"] : "NO TOPIC";
echo "Showing posts from $author about $topic";
$author = $_GET["author"] ?? "NO AUTHOR";
$topic = $_GET["topic"] ?? "NO TOPIC";
echo "Showing posts from $author about $topic";
生のPOSTデータを読み込む
通常、POSTリクエストで送信されるデータは、 application/x-www-form-urlencoded
MIMEタイプを持つ構造化キー/値ペアです。しかし、Webサービスなどの多くのアプリケーションでは、しばしばXMLまたはJSON形式の生データが代わりに送信される必要があります。このデータは、2つの方法のいずれかを使用して読み取ることができます。
php://input
は、生のリクエストボディへのアクセスを提供するストリームです。
$rawdata = file_get_contents("php://input");
// Let's say we got JSON
$decoded = json_decode($rawdata);
$HTTP_RAW_POST_DATA
は生のPOSTデータを含むグローバル変数です。これは、 php.ini
のalways_populate_raw_post_data
ディレクティブが有効な場合にのみ使用できます。
$rawdata = $HTTP_RAW_POST_DATA;
// Or maybe we get XML
$decoded = simplexml_load_string($rawdata);
この変数は、PHPのバージョン5.6以降で廃止され、PHP 7.0では削除されました。
ファイルのアップロードに使用されるコンテンツタイプがmultipart/form-data
に設定されている場合、どちらの方法も使用できないことに注意してください。
HTTP PUTでファイルをアップロードする
PHPは 、一部のクライアントがサーバー上にファイルを格納するために使用するHTTP PUTメソッドをサポートしています。 PUTリクエストは、POSTリクエストを使用したファイルアップロードよりもはるかに簡単で、次のようになります。
PUT /path/filename.html HTTP/1.1
あなたのPHPコードに次のようなことをします:
<?php
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
/* Open a file for writing */
$fp = fopen("putfile.ext", "w");
/* Read the data 1 KB at a time
and write to the file */
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
/* Close the streams */
fclose($fp);
fclose($putdata);
?>
また、 ここで 、あなたはSOのHTTP PUT経由でファイルを受信についての質問/答えを面白い読み取ることができます。
POSTによる配列の受け渡し
通常、PHPに送信されるHTMLフォーム要素は、単一の値になります。例えば:
<pre>
<?php print_r($_POST);?>
</pre>
<form method="post">
<input type="hidden" name="foo" value="bar"/>
<button type="submit">Submit</button>
</form>
これにより、次のような結果が得られます。
Array
(
[foo] => bar
)
ただし、値の配列を渡す場合があります。これは、HTML要素の名前にPHPのような接尾辞を追加することによって行うことができます:
<pre>
<?php print_r($_POST);?>
</pre>
<form method="post">
<input type="hidden" name="foo[]" value="bar"/>
<input type="hidden" name="foo[]" value="baz"/>
<button type="submit">Submit</button>
</form>
これにより、次のような結果が得られます。
Array
(
[foo] => Array
(
[0] => bar
[1] => baz
)
)
数値または文字列として配列インデックスを指定することもできます。
<pre>
<?php print_r($_POST);?>
</pre>
<form method="post">
<input type="hidden" name="foo[42]" value="bar"/>
<input type="hidden" name="foo[foo]" value="baz"/>
<button type="submit">Submit</button>
</form>
これは次の出力を返します:
Array
(
[foo] => Array
(
[42] => bar
[foo] => baz
)
)
このテクニックは、 $_POST
配列の後処理ループを避けるために使用することができます。これにより、コードがよりシンプルになり、より簡潔になります。