PHP実習:バリデーション機能を作ろう
「仮面ライダーアマゾンズ公式完全読本」が届いたので読みふけっておりました。大ファンなのでとても嬉しいです。今週土曜日には地元でも劇場版の上映が始まりますので、それまでに読破して気分を高めていきたい…。追い続けて3年目になるシリーズで語り出すと長くなるので、このくらいにしておきます。
第4章ー05 実習
バリデーション機能(フォームの入力内容に間違いがないかチェックする機能)を作る。
今回の要件定義としては、
- 空(文字数0)で送信していないかチェックする
- 20文字をオーバーしていないかチェックする
- エラーがある場合、その内容を出力する
この3点。まずはお手本通りにHTML部分を実装。
<?php
/*
POST内容を検証し、入力値が正しいかを検証
*/
?><html>
<head>
<style type="text/css">
.center{text-align: center;}
input{margin: 5px;}
</style>
</head>
<body>
<div class="center">
<h1>入力フォームを検証しよう</h1>
<p>
<?php
/*
入力フォームに間違いがあればエラーメッセージ、
正しければ「あなたの好きな映画は~です」と表示
*/
?>
</p>
<form action="" method="POST">
<label>好きな映画</label>
<input type="text" name="movie"><br>
<input type="submit">
</form>
</div>
</body>
</html>
このうち、inputタグで「action=""」としている。こうすることで、自身のファイルに向かってデータを送信することができる。
ファイルの最初のPHP部分について、以下のように変更していく。
<?php
/*
POST内容を検証し、入力値が正しいかを検証
*/
$movie=$_POST['movie'];
if(mb_strlen($movie)===0){
$err='文字を入力してください。';
}elseif(mb_strlen($movie)>20){
$err='20文字以内で入力してください。';
}
?>
$_POST['movie']を直接バリデーションせず、一度変数に入れてからバリデーションを行う。
mb_strlen()は文字列の長さを取得する組み込み関数。「mb」はマルチバイト=日本語文字を表している。mbから始まる関数は多く存在し、これらを使うと言語間の文字数の差を補正することができる。
次に、中段のPHP部を編集していく。
<?php
/*
入力フォームに間違いがあればエラーメッセージ、
正しければ「あなたの好きな映画は~です」と表示
*/
if(isset($err)){
echo $err;
}else{
echo 'あなたの好きな映画は'.$movie.'です。';
}
?>
isset()は「イズセット」と読み、変数がすでにセットされているかを調べる関数。変数は値を入寮した時点で存在することになり、今回の$errについてはエラーとなる条件(文字数0もしくは文字数が20より大きい)にかからないと生成(=初期化)されない。よって、isset()で判定をかけるようにしている。
ここで一度ブラウザで確認。
上手くいっているように見えるが、PuTTYにはこのような注意が出ている。
スクショへたくそ…。注意を見る限り、5行目に何かあるらしい。現在、5行目には「$movie=$_POST['movie'];」が書かれている。
最初にこのページを開いた時点ではPOSTのデータの取得は行っていない、つまり$_POST['movie']は存在していないのでUndefinedという注意が出ている。
これに対応するため、最初のPHPを以下のように変更。
<?php
/*
POST内容を検証し、入力値が正しいかを検証
*/
$movie='';
if ($_SERVER['REQUEST_METHOD']==='POST') {
$movie=$_POST['movie'];
if(mb_strlen($movie)===0){
$err='文字を入力してください。';
}elseif(mb_strlen($movie)>20){
$err='20文字以内で入力してください。';
}
}?>
まず、$movieに空文字を入れておく。これでUndefinedは出なくなる。
$_SERVER['REQUEST_METHOD']についてだが、$_SERVERもスーパーグローバル変数の一種であり、自動で生成される。今回はキーにREQUEST_METHODを指定することでPOSTされてきたかどうかを判定することができるようになる。
これで実習課題が完成したので、動作確認を行ってスクショで発表。
まずは最初にアクセスしたとき。
次に、このまま送信ボタンを押したとき。
エラーメッセージである「文字を入力してください。」が表示された。
入力欄に「仮面ライダーアマゾンズ THEMOVIE 最後ノ審判」と入力。
はじかれた…(´・ω・)
最後に、「劇場版仮面ライダーアマゾンズ」と入力。
そうですその通りです。君、よくわかってるじゃないか。
これにて、今回の実習課題は終了。
しかし、個人的に不満が一つ。
最初にこのページを表示したとき、「あなたの好きな映画はです。」と表示されている。まだ何もこのページに入力していない段階なので、これが見えているのはどうかと思う。なので、
- 最初にページにアクセスした際には「あなたの好きな映画を教えてください。」と表示
- 文字数0で送信した場合は「文字を入力してください。」とメッセージを出す
- 文字数が20を超えているときに送信した場合は「20文字以内で入力してください」とメッセージを出す
- 上記のエラー条件に引っかからない場合、「あなたの好きな映画は(入力した文字列)です。」と表示する。
この条件を満たすようコードを変更する。
中段のPHP部分を次のように変更。
<?php
/*
入力フォームに間違いがあればエラーメッセージ、
正しければ「あなたの好きな映画は~です」と表示
*/
if(isset($err)===false && $movie===''){
echo "あなたの好きな映画を教えてください。";
}elseif(isset($err)){
echo $err;
}else{
echo 'あなたの好きな映画は'.$movie.'です。';
}
?>
最初のコードのif条件で「if(isset($err))」と書いていたので、これは論理値で判定するものだと推測。そこで、
- $errが存在しない、かつ$movieが空のときは「あなたの好きな映画を教えてください。」と表示
- $errが存在し、かつ$movieが何らかのエラーにかかる場合はエラーメッセージを表示
- どちらにも当てはまらない(=$errが存在せず、$movieがエラーにかからない形)場合は「あなたの好きな映画は〇〇です。」と表示
という3パターンに分岐するようにした。
これで個人的には満足いくものになったので、今度こそ実習終了。
最後にifと同じような働きをすることができるswitchについておさらい。
これは分岐が多い場合に使うとよい。
<?php
$language = 2;
switch($language){
case 1: //$language==1の場合
echo 'こんにちは';
break; //ここでswitch内の処理を終了する
case 2:
echo 'Hello';
break;
case 3:
echo 'Bonjour;
break;
default: // その他 = else
echo '入力した値が間違っています';
}
switchで注意する点は、判定の際に「==」を用いているということ。整数の2と文字列の2、論理値のTrueと文字列のTrueが等しいと判断されてしまうので注意。
今夜はここまで。
仮面ライダーアマゾンズはいいぞん!!!!