filter_input関数を使って簡潔なコードを書こう
filter_input関数ってなに?
(HTMLフォームのinputタグなどから)外部変数を受け取り、フィルタリングする関数。 一般的には、ユーザが入力した値などが妥当であるか調べたりするのに使います。
利点
通常フォームなどから値を受けとるとき、以下のように書くと思います。
$id = $_GET['id']; $name = $_POST['name'];
しかし、値が入っていなかったり、上手く渡っていなかった場合、Notice: Undefined index
なんかが発生します。早い話エラーですね。
そのためissetを使用し、値が入っているか確認する必要性があります。
<?php if (!isset($_POST['name'])) { $name = null; } elseif (!is_string($_POST['name'])) { $name = false; } else { $name = $_POST['name']; }
filter_inputを使えば上のコードを1行にできます。便利ですね。
$name = filter_input(INPUT_POST, 'name');
構文
filter_input(input_type, variable, filter, options);
- input_type 入力タイプの指定。HTMLのフォームならば、INPUT_GET、INPUT_POSTなどを指定。
- variable フィルタする変数の指定。
- filter 使用するフィルタの種類。たとえば、Eメール以外を弾きたいならばFILTER_VALIDATE_EMAILと記す。
- options フラグ、オプションの連想配列あるいは単一のフラグ、オプションを指定。
変数(variable)に入っている値が空だとfalseをリターンします。
第1、2引数は必ず指定しなくてはなりません。第3、4引数は任意です。
filter_input関数を使って新規会員登録ページを実装してみよう
以上の知識を駆使して会員登録のデモページを実装してみましょう。
<?php /* 新たにユーザ登録するためのページ */ // POSTによる送信があった if (!empty($_POST)) { if (!$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_SPECIAL_CHARS)) { $error['name'] = 'ユーザ名が空です'; } if (strlen($name) > 26) { $error['name'] = '名前は25文字以内にしてください'; } if (!$pass = filter_input(INPUT_POST, 'pass', FILTER_SANITIZE_SPECIAL_CHARS)) { $error['pass'] = 'パスワードを入力してください'; } if (!empty($pass) && strlen($pass) <= 4) { $error['pass'] = 'パスワードが短すぎます'; } if (!(strlen($pass) === mb_strlen($pass))) { $error['pass'] = 'パスワードに全角が含まれています。すべて半角で入力してください'; } echo 'ユーザ名'.$name.'<br>'; echo 'パスワード'.$pass.'<br>'; } /* サニタイジング用関数 */ function sani($str) { return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); } ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>新規会員登録</title> </head> <body> <h1>新規登録</h1> <p>必要事項をご記入ください。パスワードは5文字以上、半角英数字で入力してください</p> <form action="" method="post" enctype="multipart/form-data"> <dl> <dt>ユーザー名<font color="red"> 必須</font></dt> <dd> <input type="text" name="name" size="35" maxlength="25" value=""> <?php if(!empty($error['name'])): ?> <p><font color="red"><?=sani($error['name'])?></font></p> <?php endif; ?> </dd> <dt>パスワード<font color="red"> 必須</font></dt> <dd> <input type="password" name="pass" size="10" maxlength="20" value=""> <?php if(!empty($error['pass'])): ?> <p><font color="red"><?=sani($error['pass'])?></font></p> <?php endif; ?> </dd> </dl> <div><input type="submit" value="入力内容を確認"></div> </form> </body> </html>
filter_inputの引数に指定してあるFILTER_SANITIZE_SPECIAL_CHARSはサニタイジングを実行してくれます。 ためしに、自分自身でXSSによる攻撃をしてみると、無毒化された状態でechoされるのがわかると思います。余談ですが、inputタグのpassword は、コピペにより全角入力される危険性があります。きちんと、全角を弾く処理を実装しましょう。
実際に登録ページとして使いたい場合には、php部分を以下のように改良してみるといいでしょう。
<?php /* 新たにユーザ登録するためのページ 名前とパスワードを入力させ、確認ページへと飛ばす */ @session_start(); // POSTによる送信があった if (!empty($_POST)) { if (!$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_SPECIAL_CHARS)) { $error['name'] = 'ユーザ名が空です'; } if (strlen($name) > 26) { $error['name'] = '名前は25文字以内にしてください'; } if (!$pass = filter_input(INPUT_POST, 'pass', FILTER_SANITIZE_SPECIAL_CHARS)) { $error['pass'] = 'パスワードを入力してください'; } if (!empty($pass) && strlen($pass) <= 4) { $error['pass'] = 'パスワードが短すぎます'; } if (!(strlen($pass) === mb_strlen($pass))) { $error['pass'] = 'パスワードに全角が含まれています。すべて半角で入力してください'; } // エラーがないとき確認画面へ飛ばす if (empty($error)) { $_SESSION['join'] = $_POST; header('Location: check.php'); exit(); } } // --以下略--
あとは、実際に確認用のページ(ここではcheck.php)を制作すれば良いでしょう。そして、向こう側で送信ボタンが押されればデータベースに 登録、という形にするのがオーソドックスかと思います。ここでは確認用ページにセッション変数に代入して送っているという想定ですが、 $_POSTをそのまま送っているので確認ページで無毒化してあげましょう。
ここではfilter_inputの説明をするためにコードを簡潔にしています。脆弱性があるので、そのまま使用するのは避けましょう。
あと可読性も低いですね。