こんなツイートをしました。今回はもう少し詳しくバリデーションについて説明します。
PHPのバリデーションとは
— Tomoya (@div_tomo) August 20, 2023
フォームに入力されたデータはサーバーに送信されます。そこでPHP等の言語を使ってデータを処理することになる、送信データが正しい形式のデータであるかどうかや想定した文字数の範囲か、適切なデータ型なのかをチェックするのがバリデーション機能です。#php
この記事では、バリデーション処理の記事を作成しています。
お問い合わせフォームの実装についての記事
【PHP】①お問い合わせフォーム 実装
セキュリティ対策についての記事
【PHP】②お問い合わせフォーム セキュリティ対策
※[【PHP】①お問い合わせフォーム 実装 ] と [【PHP】②お問い合わせフォーム セキュリティ対策] も同時に実施すると理解度が深まります。
手順
入力画面にお問い合わせ内容を追加
input.phpファイルの入力画面に「お問い合わせ内容を追加します。」
<!-- 追加 -->
と記載されているお問い合わせ内容のコードをコピペで問題ないので貼り付けておきましょう。
form > input.php
<!-- 入力画面 -->
<?php if($pageFlag === 0) : ?>
<?php
if(!isset($_SESSION['csrfToken']))
{
$csrfToken = bin2hex(random_bytes(32));
$_SESSION['csrfToken'] = $csrfToken;
}
$token = $_SESSION['csrfToken'];
?>
<form method="POST" action="input.php">
氏名<br>
<input type="text" name="name" value="<?php if(!empty($_POST['name'])){ echo hsc($_POST['name']) ; } ?>"><br>
メールアドレス<br>
<input type="email" name="email" value="<?php if(!empty($_POST['email'])){ echo hsc($_POST['email']) ; } ?>"><br>
<!-- 追加 -->
お問い合わせ内容<br>
<textarea name="contact">
<?php if(!empty($_POST['contact'])){ echo hsc($_POST['contact']) ; } ?>
</textarea><br>
<input type="submit" name="btn_confirm" value="確認する">
<input type="hidden" name="csrf" value="<?php echo $token; ?>">
</form>
<?php endif; ?>
説明
お問い合わせ内容は一行では無い可能性があるので textareaタグ を使って複数行入力できるように設定しています。
textareaタグ の場合バリューという値が無いので、タグの中に書いた値「<textarea name="contact">ここがバリュー</textarea>
」がバリューになります。
お問い合わせ内容にも戻るボタンを押した時に値を持たせたままにしたいので <?php if(!empty($_POST['contact'])){ echo hsc($_POST['contact']) ; } ?>
を書いてあげます。
お問い合わせ内容<br>
<textarea name="contact">
<?php if(!empty($_POST['contact'])){ echo hsc($_POST['contact']) ; } ?>
</textarea><br>
確認画面にお問い合わせ内容を追加
次にinput.phpファイルの確認画面にも「お問い合わせ内容を追加します。」
<!-- 追加 -->
と記載されているお問い合わせ内容のコードをコピペで問題ないので貼り付けておきましょう。
form > input.php
<!-- 確認画面 -->
<?php if($pageFlag === 1) : ?>
<?php if($_POST['csrf'] === $_SESSION['csrfToken']) : ?>
<form method="POST" action="input.php">
氏名
<?php echo hsc($_POST['name']) ;?>
<br>
メールアドレス
<?php echo hsc($_POST['email']) ;?>
<br>
<!-- 追加 -->
お問い合わせ内容
<?php echo hsc($_POST['contact']) ;?>
<br>
<input type="submit" name="back" value="戻る">
<input type="submit" name="btn_submit" value="送信する">
<input type="hidden" name="name" value="<?php echo hsc($_POST['name']) ;?>">
<input type="hidden" name="email" value="<?php echo hsc($_POST['email']) ;?>">
<input type="hidden" name="contact" value="<?php echo hsc($_POST['contact']) ;?>"> <!-- 追加 -->
<input type="hidden" name="csrf" value="<?php echo hsc($_POST['csrf']) ;?>">
</form>
<?php endif; ?>
<?php endif; ?>
説明
<?php echo hsc($_POST['contact']) ;?>
で入力された値を表示
お問い合わせ内容
<?php echo hsc($_POST['contact']) ;?>
<br>
戻るボタンを押しても値を残しておけるような処理を記載しています。
<input type="hidden" name="contact" value="<?php echo hsc($_POST['contact']) ;?>">
バリデーション処理
今回は入力画面にエラーメッセージを表示する方法でバリデーションの実装をしていきます。
バリデーションのコードが少し長くなるのでバリデーションのファイルを分けて作成していくことにします。
バリデーションフォルダ作成
まずformフォルダの中にvalidation.phpファイルを追加で作ってあげます。
from
|
|----> input.php
validation.php //追加
バリデーション処理を書く
関数を作ってバリデーションをかけていく処理を記載していきます。
from > validation.php
<?php
function validation($request) //$requestには$_POSTの連想配列が入る
{
$errors = []; //ローカル変数なのでinput.phpにも$errorsを記載してあげる必要がある
if(empty($request['name']) || 20 < mb_strlen($request['name'])) //nameが空だったら$errorsにエラー文の値を追加してあげる
{
$errors[] = '氏名は必須です。[20文字いないで入力してください]';
}
if(empty($request['email']) || !filter_var($request['email'], FILTER_VALIDATE_EMAIL)) //一つ目の引数がフィルターをかけたい値 //二つ目の引数でメールアドレスかどうか
{
$errors[] = 'メールアドレスは必須です。正しい形式で入力してください。';
}
if(empty($request['contact']))
{
$errors[] = 'お問い合わせ内容は必須です。';
}
return $errors; //$errorsを返す
}
?>
説明
function validation($request) //$requestには$_POSTの連想配列が入る
まず function
で validation()
関数を作ります。
引数の $request
には $_POST
の値が入ります。
$errors = [];
エラー内容をまとめて保管するために $error = []
という配列を作っています。
if(empty($request['name'] || || 20 < mb_strlen($request['name'])) //nameが空だったら$errorsにエラー文の値を追加してあげる
{
$errors[] = '氏名は必須です。[20文字いないで入力してください]';
}
name
が空だったら $errors
に'氏名は必須です。[20文字いないで入力してください]'
という値を追加する処理
もしくは
name
が20文字より多かったら$errors
に'氏名は必須です。[20文字いないで入力してください]'
という値を追加する処理
if(empty($request['email']) || !filter_var($request['email'], FILTER_VALIDATE_EMAIL)) //filter_varの一つ目の引数がフィルターをかけたい値 //二つ目の引数でメールアドレスかどうか
{
$errors[] = 'メールアドレスは必須です。正しい形式で入力してください。'
}
email
が空だったら $errors
に'メールアドレスは必須です。正しい形式で入力してください。'
という値を追加する処理
もしくは
email
が正しい形式じゃなかったら $errors
に'メールアドレスは必須です。正しい形式で入力してください。'
という値を追加する処理
if(empty($request['contact'])) //nameが空だったら$errorsにエラー文の値を追加してあげる
{
$errors[] = 'お問い合わせ内容は必須です。';
}
return $errors;
contact
が空だったら $errors
にお問い合わせ内容は必須です。
という値を追加する処理
return
で $errors
を返してあげます。
input.php で関数を使用する
▼長いのでCtrl+F
で「追加」と検索して調べると追加された箇所を確認できます
from > input
<?php
session_start();
require 'validation.php'; //追加
$errors = validation($_POST); //追加
$pageFlag = 0;
// 入力画面の値が空では無かったら$pageFlagを1に変更
if(!empty($_POST['btn_confirm']) && empty($errors)){ // 追加でエラーが空だったら処理を実行
$pageFlag = 1;
}
// 送信画面の値が空では無かったら$pageFlagを2に変更
if(!empty($_POST['btn_submit'])){
$pageFlag = 2;
}
function hsc($str)
{
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
?>
<!DOCTYPE html>
<meta charset="utf-8">
<head></head>
<body>
<!-- 入力画面 -->
<?php if($pageFlag === 0) : ?>
<?php
if(!isset($_SESSION['csrfToken']))
{
$csrfToken = bin2hex(random_bytes(32));
$_SESSION['csrfToken'] = $csrfToken;
}
$token = $_SESSION['csrfToken'];
?>
<form method="POST" action="input.php">
<!-- エラーがあったら処理を実行
初めて入力画面を表示する時にも値が空なのでエラーを表示してしまうので
追加で確認ボタンが押されたらという条件も追加 -->
<?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; ?>
氏名<br>
<input type="text" name="name" value="<?php if(!empty($_POST['name'])){ echo hsc($_POST['name']) ; } ?>"><br>
メールアドレス<br>
<input type="email" name="email" value="<?php if(!empty($_POST['email'])){ echo hsc($_POST['email']) ; } ?>"><br>
お問い合わせ内容<br>
<textarea name="contact"><?php if(!empty($_POST['contact'])){ echo hsc($_POST['contact']) ; } ?></textarea><br>
<input type="submit" name="btn_confirm" value="確認する">
<input type="hidden" name="csrf" value="<?php echo $token; ?>">
</form>
<?php endif; ?>
<!-- 確認画面 -->
<?php if($pageFlag === 1) : ?>
<?php if($_POST['csrf'] === $_SESSION['csrfToken']) : ?>
<form method="POST" action="input.php">
氏名
<?php echo hsc($_POST['name']) ;?>
<br>
メールアドレス
<?php echo hsc($_POST['email']) ;?>
<br>
お問い合わせ内容
<?php echo hsc($_POST['contact']) ;?>
<br>
<input type="submit" name="back" value="戻る">
<input type="submit" name="btn_submit" value="送信する">
<input type="hidden" name="name" value="<?php echo hsc($_POST['name']) ;?>">
<input type="hidden" name="email" value="<?php echo hsc($_POST['email']) ;?>">
<input type="hidden" name="contact" value="<?php echo hsc($_POST['contact']) ;?>">
<input type="hidden" name="csrf" value="<?php echo hsc($_POST['csrf']) ;?>">
</form>
<?php endif; ?>
<?php endif; ?>
<!-- 完了画面 -->
<?php if($pageFlag === 2) : ?>
<?php if($_POST['csrf'] === $_SESSION['csrfToken']) : ?>
<p>送信が完了しました。</p>
<?php unset($_SESSION['csrfToken']); ?>
<?php endif; ?>
<?php endif; ?>
</body>
</html>
説明
<?php
session_start();
require 'validation.php'; //追加
$errors = validation($_POST); //追加
session_start();
の下に require
で validation.php
を追加して関数を使用できるようにする
$errors = validation($_POST);
ここファイルに記載した関数を使用して $errors
に格納
if(!empty($_POST['btn_confirm']) && empty($errors)){
&& empty($errors)
エラーが空だったら処理を実行という処理を追加で記載
<!-- エラーがあったら処理を実行
初めて入力画面を表示する時にも値が空なのでエラーを表示してしまうので
追加で確認ボタンが押されたらという条件も追加 -->
<?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; ?>
!empty($errors)
エラーがあったら
かつ
!empty($_POST['btn_confirm']))
確認ボタンが押されたら実行
foreach($errors as $error)
{
echo '<li>' . $error . '</li>' ;
}
foreach で配列を1つ1つ取り出している