あーる学習帳

自分が勉強したことや気になることなど、99%自分用です。コードを書いてるのでPCから閲覧を推奨。

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>

f:id:R_de_aru:20180620224141p:plain

このうち、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()で判定をかけるようにしている。

ここで一度ブラウザで確認。

f:id:R_de_aru:20180620225303p:plain

上手くいっているように見えるが、PuTTYにはこのような注意が出ている。

f:id:R_de_aru:20180620225600p:plain

スクショへたくそ…。注意を見る限り、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されてきたかどうかを判定することができるようになる。

これで実習課題が完成したので、動作確認を行ってスクショで発表。

まずは最初にアクセスしたとき。

f:id:R_de_aru:20180620230648p:plain

次に、このまま送信ボタンを押したとき。

f:id:R_de_aru:20180620230752p:plain

エラーメッセージである「文字を入力してください。」が表示された。

入力欄に「仮面ライダーアマゾンズ THEMOVIE 最後ノ審判」と入力。

f:id:R_de_aru:20180620230933p:plain

はじかれた…(´・ω・)

最後に、「劇場版仮面ライダーアマゾンズ」と入力。

f:id:R_de_aru:20180620231104p:plain

そうですその通りです。君、よくわかってるじゃないか。

これにて、今回の実習課題は終了。

 

しかし、個人的に不満が一つ。

最初にこのページを表示したとき、「あなたの好きな映画はです。」と表示されている。まだ何もこのページに入力していない段階なので、これが見えているのはどうかと思う。なので、

  • 最初にページにアクセスした際には「あなたの好きな映画を教えてください。」と表示
  • 文字数0で送信した場合は「文字を入力してください。」とメッセージを出す
  • 文字数が20を超えているときに送信した場合は「20文字以内で入力してください」とメッセージを出す
  • 上記のエラー条件に引っかからない場合、「あなたの好きな映画は(入力した文字列)です。」と表示する。

この条件を満たすようコードを変更する。

中段のPHP部分を次のように変更。

<?php
 /*
 入力フォームに間違いがあればエラーメッセージ、
 正しければ「あなたの好きな映画は~です」と表示
 */
 if(isset($err)===false && $movie===''){
  echo "あなたの好きな映画を教えてください。";
 }elseif(isset($err)){
  echo $err;
 }else{
  echo 'あなたの好きな映画は'.$movie.'です。';
 }
?> 

最初のコードのif条件で「if(isset($err))」と書いていたので、これは論理値で判定するものだと推測。そこで、

  1. $errが存在しない、かつ$movieが空のときは「あなたの好きな映画を教えてください。」と表示
  2. $errが存在し、かつ$movieが何らかのエラーにかかる場合はエラーメッセージを表示
  3. どちらにも当てはまらない(=$errが存在せず、$movieがエラーにかからない形)場合は「あなたの好きな映画は〇〇です。」と表示

という3パターンに分岐するようにした。

f:id:R_de_aru:20180620232433p:plain

これで個人的には満足いくものになったので、今度こそ実習終了。

最後に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が等しいと判断されてしまうので注意。

 

今夜はここまで。

仮面ライダーアマゾンズはいいぞん!!!!