HTTPの基礎知識
スーパーグローバル変数
PHPではWEBサーバーへのリクエスト情報を参照したり、操作したりするためのスーパーグローバル変数をもっています。どこからでも参照できる配列です。
変数名 | 内容 |
---|---|
$_GET | GETリクエストのパラメーター。パラメーター名が配列のキーになる。 |
$_POST | POSTリクエストのパラメーター。パラメーター名が配列のキーになる。 |
$_COOKIE | クッキーの値。クッキーの名前が配列のキーになる。 |
$_SESSION | セッション変数 |
$_FILES | アップロードされたファイルの情報 |
$_SERVER | Webサーバーに関する情報 |
$_ENV | サーバー側の環境変数。環境変数名が配列のキーになる。 |
- GETはリクエストをURLのアドレスの後に?を付けて送信する。キーと値のペア部分がクエリ文字で複数のパラメーターがある場合は&でつなぐ。
- POSTはリクエストを本文に含めて送信します。リクエスト内容を簡単に見られない。
- GETのレスポンスはキャッシュされるが、POSTはキャッシュされない。
送信フォームの作成
リクエストフォーム
<form method="POST" action="calc.php">
<ul class="nolist">
<li><label>単価:<input type="number" name="tanka"></label></li>
<li><label>個数:<input type="number" name="kosu"></label></li>
<li><input type="submit" value="計算する"></li>
</ul>
</form>
POSTメソッドのフォーム
<?php
//フォーム入力の値を取り出す
$tanka = $_POST["tanka"];
$kosu = $_POST["kosu"];
//計算
$price = $tanka * $kosu;
//3桁位取り表示
$tanka = number_format($tanka);
$kosu = number_format($kosu);
$price = number_format($price);
echo "単価{$tanka}円 × {$kosu}個は{$price}円です。";
?>
GETメソッドで送信する場合
リクエストフォーム
<form method="GET" action="check.php">
<ul class="nolist">
<li><label>番号:<input type="number" name="no"></label></li>
<li><input type="submit" value="調べる"></li>
</ul>
</form>
GETメソッドのフォーム
<?php
$no = $_GET["no"];
$nolist = [2,4,6,8,10,12,14,16,18,20];
if(in_array($no,$nolist)) {
echo "{$no}はあります。";
} else {
echo "{$no}は見つかりませんでした。";
}
マルチバイト文字をURLエンコードする
GETリクエストのクエリ文字にマルチバイトが含まれている場合は、パラメーターをURLエンコードしてから添付します。
URLエンコードはrawurlencode()で行い、逆のデコードはrawurldecode()で行います。
※POSTメソッドを使う場合はPHPがエンコードとデコードを自動で行います。
GETリクエストのクエリ文字にマルチバイトが含まれている場合は、パラメーターをURLエンコードしてから添付します。
URLエンコードはrawurlencode()で行い、逆のデコードはrawurldecode()で行います。
※POSTメソッドを使う場合はPHPがエンコードとデコードを自動で行います。
クロスサイトスクリプティング(XSS 対策)
htmlspecialchars(値, ENT_QUOTES, 'UTF-8')
不正な文字をHTMLエスケープする
htmlspecialchars(値, ENT_QUOTES, 'UTF-8')
htmlspecialchars()を便利に使うためのユーザー定義関数es()
引数に対してhtmlspecialchars()を実行するes()
<?php
function es($data)
//xss 対策のための HTML エスケープ
{
if (is_array($data)) { //$dataが配列の時
return array_map(__METHOD__, $data); //値を1つずつ引数にして、再帰呼び出し
} else {
return htmlspecialchars($data, ENT_QUOTES, "UTF-8");
}
}
__METHOD__を利用した再帰呼び出し
array_map()でコールしている__METHOD__は、現在実行中のメソッド自信を指す特殊な定数(マジック定数)です。ここではes()を指すので、es()の中でes()を使っていることになります。
この手法を再帰呼び出しと言います。
array_map()でコールしている__METHOD__は、現在実行中のメソッド自信を指す特殊な定数(マジック定数)です。ここではes()を指すので、es()の中でes()を使っていることになります。
この手法を再帰呼び出しと言います。
es.phpのes()をテストする
<?php
require_once("es.php");
$myCode = "<h2>esのテスト中です</h2>";
$myArray = ["a" => "<p>配列のテスト</p>", "b" => "<script>alert('hello')</script>"];
echo '$myCodeの値:', es($myCode);
echo "\n\n";
echo '$myArrayの値:';
print_r(es($myArray));
?>
$myCodeの値:<h2>esのテスト中です</h2> $myArrayの値:Array ( [a] => <p>配列のテスト</p> [b] => <script>alert('hello')</script> )
※プログラム実行するとブラウザには変数と配列がそのまま表示されていますが、実際に出力された結果を確認すると値に含まれている特殊文字がエンティティ変換されている。
文字エンコードを行うユーザー定義関数 ckeckEn()
mb_check_encode()を使って文字エンコードのチェックを効率よく行うckeckEn()を、先のen()と同様に定義!この関数では$_GET、$_POST、$_SESSIONなどの配列に含まれている値のエンコードをチェックする前提で組む
$resultが初期値のtrueのままであれば文字コードは正しく、途中でfalceが代入されていれば、文字コードは一致していないことになります。
$resultが初期値のtrueのままであれば文字コードは正しく、途中でfalceが代入されていれば、文字コードは一致していないことになります。
配列の文字エンコードのチェック
//配列の文字エンコードのチェック
function checkEn(array $data)
{
$result = true;
foreach ($data as $key => $value) {
if (is_array($value)) { //含まれている値が配列のとき文字列に連結
$value = implode("", $value);
}
if (!mb_check_encoding($value)) { //文字コードが一致しないときfalce代入し繰り返しをブレイク
$result = false;
break;
}
}
return $result;
}
checkEn()をテスト
<?php
require_once("es.php");
$utf8_string = "こんにちは";
$sjis_string = mb_convert_encoding($utf8_string, 'Shift-JIS');
$encoding = mb_internal_encoding();
if(checkEn([$sjis_string])) {
echo "配列の値は、", $encoding, "です。";
} else {
echo "配列の値は、", $encoding, "ではありません。";
}
?>
配列の値は、UTF-8ではありません。