[Utility.php] GET, POST, COOKIE を安全に取得するfunction()

Utility.phpに記述しておきたいfunctionを掲載していきます。
記事中【 C_ 】 で始まるコードは定数です。server_dependence.phpを参照してください。

GET, POST, COOKIE を安全に取得するfunction()

GET, POST, COOKIEを取得するとき、$_GET['hoge'] のように取得しますが、
echo $_GET['hoge'];
のように、そのまま出力したり保存やコマンドの一部として使用することは、セキュリティの問題上望ましくありません。

スーパーグローバル変数を取得してみるfunction で、本記事の補足をしております。

以下で紹介するfunction()ではこういった問題を解消し、安全な形で外部変数を取得します。
説明は、コードの下に続きます。

/*
 * GET, POST, COOKIE 外部変数を取得
 *
 * [php.ini] or [.htaccess] -> php_flag register_globals Off
 *
 * @param string $Name : $_GET[$Name], $_POST[$Name], $_COOKIE[$Name]
 * @param string $Type : get, post, cookie
 * @param string $Charset : utf8, sjis, euc ... etc
 * @param bool $Decode : true = urldecode()
 */
function aulta_getOutsideVariable($Name, $Type, $Charset = "utf-8", $Decode = false)
{
  $ret = "";
  switch (strtolower($Type)){
    case "get":
      if (isset($_GET[$Name])) $ret = $_GET[$Name];
      break;
    case "post":
      if (isset($_POST[$Name])) $ret = $_POST[$Name];
      break;
    case "cookie":
      if (isset($_COOKIE[$Name])) $ret = $_COOKIE[$Name];
  }
  $ret = str_replace("\0", "", $ret);
  if (strlen($ret) > 0) {
    if ($Decode){
      $ret = str_replace("+", "%2B", $ret);
      $ret = urldecode($ret);
    }
    $ret = trim(mb_convert_encoding($ret, $Charset
      , $Charset . ", JIS, eucjp-win, sjis-win, utf-8"));
    $ret = htmlspecialchars($ret, ENT_QUOTES, $Charset);
    $ret = str_replace(''', ''', $ret);
    $ret = str_replace('"', '"', $ret);
    $ret = str_replace("rn", "n", $ret);
    $ret = str_replace("r", "n", $ret);
    return $ret;
  }
  return "";
}
[php language=".ini"][/php]

or [.htaccess] -> php_flag register_globals Off

php.ini または、.htaccessにて、register_globals を off にしてください。
参考:register_globalsとは - はてなダイアリー

戻り値について

外部変数を返します。
返される文字列のうち特殊な文字は次のように変換されています。
' -> '
" -> "
& -> &
<
> -> >
改行文字は、 n です。
詳細は、以下のコードの説明を参考にしてください。

引数について

【$Name】
get, post, cookieで取得する名前を渡します。
$_GET['hoge'], $_POST['hoge'], $_COOKIE['hoge'] の'hoge'の部分です。

【$Type】
大文字・小文字は問いません。
get, post, cookie のいずれかを渡します。

【$Charset = "utf-8"】
省略可能です。省略した場合は、"utf-8"が渡されます。
getOutsideVariable() では、指定した文字コードに変換してreturnします。
utf8, euc, sjis など、変換後のキャラセットを指定します。
なお省略時のutf-8は、php、css、javascriptなどを"utf-8"で統一することを前提にしています。他の文字コードでシステムを構築する場合は、目的にあった初期値に変更します。

【$Decode = false】
省略可能です。省略した場合は、falseが渡されます。
URLエンコード済みの外部変数を取得する時、 true を渡します。省略したデフォルト値は false です。falseでは、urlデコードを行いません。
その外部変数が、URLエンコードを施しているかいないかは、そのシステムの設計者であるあなたにしか分かりません。

getOutsideVariable() 中でやっていること

switch (strtolower($Type)){

$Type を小文字に統一し、続く case で振り分け、get, post, cookie の値を $ret に取得します。

$ret = str_replace("\0", "", $ret);

"" を str_replace で 空文字 に変換します。
理由は、[google] php ヌルバイト攻撃を見てください。

if ($Decode){
  $ret = str_replace("+", "%2B", $ret);
  $ret = urldecode($ret);
}

URLエンコードされた外部変数を取得するとき、URLデコードします。

javascript の encodeURI() でurlエンコードされた文字列を受信し、PHPのurldecode()でデコードした場合、プラス(+)になるべき文字が半角スペースに置き換わってしまいます。
これはencodeURI()で、+の文字が%2Bにurlエンコードされずに+のまま送信されてしまうことに問題があります。urlエンコードされた半角スペースは +(または%20)で表現されるので、+を半角スペースに置き換えているPHPのurldecode()は正しい処理となります。
この理由により、事前に + を %2B に置き換えたうえで、urldecode()で通常の文字列に戻しています。

$ret = trim(mb_convert_encoding($ret, $Charset
      , $Charset . ", JIS, eucjp-win, sjis-win, utf-8"));

指定の文字コードに変換することで文字化けを回避します。

$ret = htmlspecialchars($ret, ENT_QUOTES, $Charset);
$ret = str_replace(''', ''', $ret);
$ret = str_replace('"', '"', $ret);

特殊文字をHTMLエンティティに変換します。
htmlspecialchars()をすると、シングルクォート、ダブルクォートの直前に が付加されるので取り除きます。

$ret = str_replace("rn", "n", $ret);
$ret = str_replace("r", "n", $ret);

通常、windowsは rn、macは r、unixはn、がデフォルトの改行文字となっており、ユーザーのPC(ブラウザ)次第で、どの改行文字が送信されてくるか分かりません。そこで、改行文字を n に統一します。