見出し画像

【 PHP学習 #21 】 バリデーション#3 FIREへの旅路 ♯471

前回に続いて、フォームのバリデーションを追加していきます。


【 前回までのコード 】

input.php

<?php

session_start();

require 'validation.php';


header( 'X-FRAME-OPTIONS:DENY' );

//スーパーグローバル変数
if ( !empty( $_POST ) ) {

  echo '<pre>';

  var_dump( $_POST );

  echo '</pre>';

}


function h( $str ) {
  return htmlspecialchars( $str, ENT_QUOTES, 'UTF-8' );
}


//入力画面=0、確認画面=1、完了画面=2 
//表示する内容を切り替える条件を設定する
$pageFlag = 0;

//バリデーション用
$errors = validation($_POST);

if ( !empty( $_POST[ 'btn_confirm' ] )  && empty($errors)) {
  $pageFlag = 1;
}

if ( !empty( $_POST[ 'btn_submit' ] ) ) {
  $pageFlag = 2;
}


?>

<!DOCTYPE html>
<meta charset="utf-8">
<head>
</head>
<body>

<!--入力画面-->
<?php if($pageFlag === 0) : ?>

<!--csrfトークンの生成-->
<?php
if ( !isset( $_SESSION[ 'csrfToken' ] ) ) {
  $csrfToken = bin2hex( random_bytes( 32 ) );
  $_SESSION[ 'csrfToken' ] = $csrfToken;
}
$token = $_SESSION[ 'csrfToken' ]
?>
	
<!--エラーメッセージを表示する -->
<?php if(!empty($errors) && !empty($_POST ['btn_confirm'])) :?>
<?php echo '<ul>' ;?>
<?php 
	foreach($errors as $error ){
		echo '<li>' .  $error . '</li>' ;
	}
?>
	
<?php echo '</ul>' ;?>
	
	
<?php endif; ?>
	
	
	
	
	
<form method="POST" action="input.php">
  氏名
  <input type="text" name="your_name" value="<?php if(!empty($_POST['your_name'])) {echo h($_POST['your_name']);} ?>">
  <br>
  メールアドレス
  <input type="text" name="email" value="<?php if(!empty($_POST['email'])) {echo h($_POST['email']);} ?>">
  <br>
  ホームページ
  <input type="url" name="url" value="<?php if(!empty($_POST['url'])) {echo h($_POST['url']);} ?>">
  <br>
  性別
  <input type="radio" name="gender" value="0"
  <?php if(isset($_POST['gender']) && $_POST['gender'] ===  '0') { echo 'checked';} ?>>男性
  
  <input type="radio" name="gender" value="1"
  <?php if(isset($_POST['gender']) && $_POST['gender'] ===  '1') { echo 'checked';} ?>>女性 
	
  <br>
	
  年齢
  <select name="age">
    <option value="">選択してください</option>
    <option value="1" <?php if(isset($_POST['age']) && $_POST['age'] === '1' )  { echo 'selected'; } ?>>〜19歳</option>
    <option value="2" <?php if(isset($_POST['age']) && $_POST['age'] === '2' )  { echo 'selected'; } ?>>20歳〜29歳</option>
    <option value="3" <?php if(isset($_POST['age']) && $_POST['age'] === '3' )  { echo 'selected'; } ?>>30歳〜39歳</option>
    <option value="4" <?php if(isset($_POST['age']) && $_POST['age'] === '4' )  { echo 'selected'; } ?>>40歳〜49歳</option>
    <option value="5" <?php if(isset($_POST['age']) && $_POST['age'] === '5' )  { echo 'selected'; } ?>>50歳〜59歳</option>
    <option value="6" <?php if(isset($_POST['age']) && $_POST['age'] === '6' )  { echo 'selected'; } ?>>60歳〜</option>
  </select>
  <br>
  お問い合わせ内容
  <textarea name="contact">
	  <?php if(!empty($_POST['contact'])) {echo h($_POST['contact']);} ?>
  </textarea>
  <br>
  <input type="checkbox" name="caution" value="1">
  注意事項にチェックする <br>
  <input type="submit" name="btn_confirm" value="確認する">
  
  <!--csrfトークンを仕込む-->
  <input type="hidden" name="csrf" value="<?php echo $token; ?>" >
</form>
<?php endif; ?>

	
	
<!--確認画面-->
<?php if($pageFlag === 1) :?>

<!--POSTのcsrfとSESSIONのcsrfがあっているか判定する-->
<?php if($_POST['csrf'] === $_SESSION['csrfToken']): ?>
<form method="POST" action="input.php">
	
  氏名 <?php echo h($_POST['your_name']);?> 
	
  <br>
	
  メールアドレス <?php echo h($_POST['email']);?> 
	
  <br>
	
  ホームページ<?php echo h($_POST['url']);?> 
	
  <br>
	
  性別
  <?php
	if($_POST['gender'] === '0'){echo '男性';}
	if($_POST['gender'] === '1'){echo '女性';}
  ?> 
	
  <br>
	
  年齢
  <?php
	if($_POST['age'] === '1'){echo '〜19歳';}
	if($_POST['age'] === '2'){echo '20歳〜29歳';}
	if($_POST['age'] === '3'){echo '30歳〜39歳';}
	if($_POST['age'] === '4'){echo '40歳〜49歳';}
	if($_POST['age'] === '5'){echo '50歳〜59歳';}
	if($_POST['age'] === '6'){echo '60歳〜';}
  ?> 
	
	
  <br>
	
  問い合わせ内容<?php echo h($_POST['contact']);?> 
	
  <br>
	

  
  <!--戻るボタン-->
  <input type="submit" name="back" value="戻る">
  
  <!--送信ボタン-->
  <input type="submit" name="btn_submit" value="送信する">
	
  <!--入力内容を保存-->
  <input type="hidden" name="your_name" value="<?php echo h($_POST['your_name']);?>" >
  <input type="hidden" name="email" value="<?php echo h($_POST['email']);?>" >
  <input type="hidden" name="url" value="<?php echo h($_POST['url']);?>" >
  <input type="hidden" name="gender" value="<?php echo h($_POST['gender']);?>" >
  <input type="hidden" name="age" value="<?php echo h($_POST['age']);?>" >
  <input type="hidden" name="contact" value="<?php echo h($_POST['contact']);?>" >
	
  
  <!--$pageFlagが0から1に変わる時にcsrfの値も消えるので、保存しておく-->
  <input type="hidden" name="csrf" value="<?php echo h($_POST['csrf']);?>" >
</form>
<?php endif; ?>
<?php endif; ?>

<!--完了画面-->
<?php if($pageFlag === 2) : ?>

<!--POSTのcsrfとSESSIONのcsrfが一致しているか判定する-->
<?php if($_POST['csrf'] === $_SESSION['csrfToken']): ?>
送信が完了しました 

<!--トークンを削除する-->
<?php unset($_SESSION['csrfToken']); ?>
<?php endif; ?>
<?php endif; ?>
</body>
</html>


validation.php

<?php

function validation($request){ //$_POST連想配列が入る
	
	$errors = [];
	
	if(empty($request['your_name'])){
		
		$errors[] = '氏名は必須です';
		
	}
	
	return $errors;
}




?>

前回までのコードでは、氏名の項目が空白であったら、
’氏名は必須です’というエラーメッセージを表示するようになっています。


【 バリデーションの追加 】

フォームの全項目にバリデーションを追加します。

入力項目を空欄で「確認する」ボタンをクリックするとエラーメッセージが表示されます。



【 全コード 】

input.phpはそのままです。
validation.phpを追記します。

validation.php

<?php

function validation($request){ //$_POST連想配列が入る
	
	$errors = [];
	
	
	//氏名の項目のエラーメッセージ ・・・・・・解説①
	if(empty($request['your_name']) || 20 < mb_strlen($request['your_name'])){
		
		$errors[] = '「氏名」は必須です。20文字以内で入力してください。';
		
	}
	
	
	//メールアドレスの項目のエラーメッセージ ・・・・・・解説②
	if(empty($request['email']) || !filter_var($request['email'], FILTER_VALIDATE_EMAIL)){
		
		$errors[] = '「メールアドレス」は必須です。正しい形式で入力してください。';
	}
	
	
	//ホームページの項目のエラーメッセージ ・・・・・解説③
	if(!empty($request['url'])) {
		
		if(!filter_var ($request['url'], FILTER_VALIDATE_URL)){
			
			$errors[] = '「ホームページ」は正しい形式で入力してください。';
		}
	}

	
	//性別の項目のエラーメッセージ ・・・・・解説④
	if(!isset($request['gender'])){
		
		$errors[] = '「性別」は必須です。';
	}
	
	



	
	
	//問い合わせ内容の項目のエラーメッセージ ・・・・・解説⑥
	if(empty($request['contact']) || 200 < mb_strlen($request['contact'])){
		
		$errors[] = '「お問い合わせ内容」は必須です。200文字以内で入力してください。';
		
	}
	
	
	
	//注意事項にチェックするボタンのエラーメッセージ ・・・・・解説⑦
	if(empty($request['caution'])){
		
		$errors[] = '「注意事項」をご確認ください。';
	}
	
	
	
	return $errors;
}




?>



・ 解説①   氏名の項目


	//氏名の項目のエラーメッセージ ・・・・・・解説①
	if(empty($request['your_name']) || 20 < mb_strlen($request['your_name'])){
		
		$errors[] = '「氏名」は必須です。20文字以内で入力してください。';
		
	}

もしも( if )
$request の配列の'your_name' 
の 値が
空だったら ( empty )
または ( || )
$request
の配列の'your_name' の 値が
20文字
以上だったら( 20 < mb_strlen['your_name'] )

$error の配列の値に、
'「氏名」は必須です。20文字以内で入力してください。'
を、入れる。

という内容です。



解説②  メールアドレスの項目


	//メールアドレスの項目のエラーメッセージ ・・・・・・解説②
	if(empty($request['email']) || !filter_var($request['email'], FILTER_VALIDATE_EMAIL)){
		
		$errors[] = '「メールアドレス」は必須です。正しい形式で入力してください。';
	}

▶︎  filter_var

指定したフィルタでデータをフィルタリングする

filter_var ( フィルタリングする対象 , 指定フィルタ )

という形で書いています。

フィルタリングする対象が、$request配列の、'email'の値です。
指定フィルタが、FILTER_VALIDATE_EMAILというフィルタを指定しています。


▶︎ 検証フィルタ

PHPには、検証フィルタが多数用意されています。

今回の場合は、メールアドレスかどうかを検証したいので、
FILTER_VALIDATE_EMAILというフィルタを選択しています。


・ 解説③  ホームページの項目


	//ホームページの項目のエラーメッセージ ・・・・・解説③
	if(!empty($request['url'])) {
		
		if(!filter_var ($request['url'], FILTER_VALIDATE_URL)){
			
			$errors[] = '「ホームページ」は正しい形式で入力してください。';
		}
	}

email のバリデーションと同様に、
filter_varを使って、フィルタリングします。

urlの検証用のフィルタは、
FILTER_VALIDATE_URL です。

ホームページの入力は、ホームページがない場合には、空欄で良いので、
エラーメッセージが出る条件としては、入力欄に、入力されていたら、検証して、エラーメッセージを表示するようにします。

もしも( if )
$requestの配列の'url' の値が、
空でなかった場合は、( !empty )

FILTER_VALIDATE_URLを使って
検証して、urlでなければ、( !filter_var )
$errorsの配列の値に、
「ホームページ」は正しい形式で入力してください
。を入れる

という内容です。


・  解説④   性別の項目


	//性別の項目のエラーメッセージ ・・・・・解説④
	if(!isset($request['gender'])){
		
		$errors[] = '「性別」は必須です。';
	}
	

性別の項目は、ラジオボタンが押されていなければ、エラーメッセージを出すので,

isset を使って判定します。

もしも( if )
$request
の配列 'gender'の値が、
設定されていなかったら( !isset )
$errors の配列にの値に、「性別」は必須です。 を入れる。

とう内容になります。



・  解説⑤  年齢の項目

	//年齢の項目のエラーメッセージ ・・・・・解説⑤
	if(empty($request['age']) || 6 < $request['age']){
		
		$errors[] = '「年齢」は必須です。';
		
	}

年齢は、選択されてるかどうか(空かどうか)と、
値が、6より小さいことを条件に、エラーメッセージを表示します。

もしも( if )
$request
 の配列 'age' の値が、
空だったら( empty )

または、( || )

$request の配列 'age' の値が、
6より大きかったら( 6 <  $request['age'] 

という内容です。


・ 解説⑥  問い合わせ内容の項目


	//問い合わせ内容の項目のエラーメッセージ ・・・・・解説⑥
	if(empty($request['contact']) || 200 < mb_strlen($request['contact'])){
		
		$errors[] = '「お問い合わせ内容」は必須です。200文字以内で入力してください。';
		
	}

もしも( if )
$request の配列の'contact' 
の 値が
空だったら ( empty )
または ( || )
$request
の配列の'contact' の 値が
200文字
以上だったら( 20 < mb_strlen['your_name'] )

$error の配列の値に、
'「お問い合わせ内容」は必須です。200文字以内で入力してください。'
を、入れる。



・ 解説⑦  注意事項にチェックする

	//注意事項にチェックするボタンのエラーメッセージ ・・・・・解説⑦
	if(empty($request['caution'])){
		
		$errors[] = '「注意事項」をご確認ください。';
	}

emptyを使って、空かどうかを判定して、エラーメッセージを出します。

もしも( if )
$request の配列 の  'caution' の値が、
空だったら ( empty )
$errors の 配列の値に、
'「注意事項」をご確認ください。' を入れる。

とう内容です。



・ 確認 

ブラウザで、確認しましょう!!!


空欄であるため、
エラーメッセージが出ています。

これで、各項目のバリデーションが完了!!!


この記事が気に入ったらサポートをしてみませんか?