フォーム~入力処理~

PHPのシンタックス

  1. HOME
  2. フォーム~入力処理~

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がエンコードとデコードを自動で行います。

クロスサイトスクリプティング(XSS 対策)
htmlspecialchars(値, ENT_QUOTES, 'UTF-8')
不正な文字をHTMLエスケープする

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()を使っていることになります。
この手法を再帰呼び出しと言います。

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が代入されていれば、文字コードは一致していないことになります。

配列の文字エンコードのチェック

//配列の文字エンコードのチェック
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ではありません。