SHINYA TECH

公務員(行政職)から34歳でエンジニア転職した人

#17 Web版読書ログサービスの作成 ~ バリデーション処理 ~

f:id:kshinya-tech:20220226144751p:plain

#14 でHTMLのフォーム欄を作成し、#15 でフォームへの入力をデータベースに格納できるようにしました。

shinya-tech.com

shinya-tech.com

今回は、フォームに入力された値をチェックして、意図しない値の場合、エラーメッセージが表示されるようバリデーション関数を定義しました。

以下、コード内コメント参照。

<?php
// mysqli.phpファイルを読み込む
require_once __DIR__ . '/lib/mysqli.php';

// データベースへのデータの登録する関数を定義
function createCompany($link, $company)
{
    $sql = <<<EOT
INSERT INTO companies (
    name,
    establishment_date,
    founder
) VALUES (
    "{$company['name']}",
    "{$company['establishment_date']}",
    "{$company['founder']}"
);
EOT;
    $result = mysqli_query($link, $sql);
    if (!$result) {
        error_log('Error: fail to create company');
        error_log('Debugging Error: ' . mysqli_error($link));
    }
}

// バリデーション関数を定義
function validate($company)
{
    // エラーは複数発生しうるので配列で格納する
    $errors = [];

    // 会社名についてのバリデーション
    // 空欄及び文字列の最大値を超えていないかチェック
    if (!strlen($company['name'])) {
        $errors['name'] = '会社名を入力してください';
    } elseif (strlen($company['name']) > 255) {
        $errors['name'] = '会社名は255文字以内で入力してください';
    }

    // 設立日についてのバリデーション
    // 条件1 : 空欄の場合にエラー
    // 条件2 : 日付の形式(YYYY-MM-DD)でない場合にエラー
    // 条件3 : ありえない日付の場合にエラー

    // 条件3でcheckdate()を使用するため、'-'で日付を区切って配列として格納
    // 例)2020-10-8 -> 2020 10 8 に分割する
    $dates = explode('-', $company['establishment_date']);

    if (!strlen($company['establishment_date'])) {
        $errors['establishment_date'] = '設立日を入力してください';
    } elseif (count($dates) !== 3) {
        $errors['establishment_date'] = '設立日を正しい形式で入力してください';

        // checkdateの引数は(月,日,年)とする必要があるため、以下のようにする。
    } elseif (!checkdate($dates[1], $dates[2], $dates[0])) {
        $errors['establishment_date'] = '設立日を正しい日付で入力してください';
    }

    // 代表者についてのバリデーション
    // 空欄及び文字列の最大値を超えていないかチェック
    if (!strlen($company['founder'])) {
        $errors['founder'] = '代表者を入力してください';
    } elseif (strlen($company['founder']) > 255) {
        $errors['founder'] = '代表者は255文字以内で入力してください';
    }

    return $errors;
}

// HTTPメソッドがPOSTだったら
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // POSTされた会社情報を変数に格納する
    $company = [
        'name' => $_POST['name'],
        'establishment_date' => $_POST['establishment_date'],
        'founder' => $_POST['founder'],
    ];
    // バリデーションする
    $errors = validate($company);
    // バリデーションエラーがなければ
    if (!count($errors)) {
        // データベースに接続する
        $link = dbConnect();
        // データベースにデータを登録する
        createCompany($link, $company);
        // データベースとの接続を切断する
        mysqli_close($link);
        header("Location: index.php");
    }
    // もしエラーがあれば,以下に処理を続行(※)
}
?>

<!-- (※)あまり美しくないが、とりあえずバリデーション処理が正常に行われているか確認するため、HTMLをベタ打ち -->
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>会社情報の登録</title>
</head>

<body>
    <h1>会社情報の登録</h1>
    <form action="create.php" method="post">
        <!-- バリデーションエラーを表示させる -->
        <?php if (count($errors)) : ?>
            <ul>
                <?php foreach ($errors as $error) : ?>
                    <li><?php echo $error; ?></li>
                <?php endforeach; ?>
            </ul>
        <?php endif; ?>

        <div>
            <label for="name">会社名</label>
            <input type="text" id="name" name="name">
        </div>
        <div>
            <label for="establishment_date">設立日</label>
            <input type="date" name="establishment_date" id="establishment_date">
        </div>
        <div>
            <label for="founder">代表者</label>
            <input type="text" name="founder" id="founder">
        </div>
        <button type="submit">登録する</button>
    </form>
</body>

</html>