引き続きCRUD処理の開発を進めていきましょう。次はカテゴリー作成処理を実装します。
ここでは以下の手順にしたがってプログラムを作成します。
- カテゴリー一覧画面の修正 -
index.php
- カテゴリー作成画面の作成 -
create.php
- カテゴリー作成処理の実装 -
store.php
1. カテゴリー一覧画面の修正 - index.php
index.php
ファイルのHTMLコードにカテゴリー作成画面へのリンクを追加します。
...省略
<body>
<h3>Categories - Index</h3>
<hr>
<table border="1">
<tr>
<th>ID</th>
<th>TITLE</th>
</tr>
<?php foreach ($categories as $category) { ?>
<tr>
<td><?= htmlspecialchars($category["id"]) ?></td>
<td><?= htmlspecialchars($category["title"]) ?></td>
</tr>
<?php } ?>
</table>
<hr>
<a href="create.php">CREATE</a>
</body>
</html>
カテゴリー作成画面の作成 - create.php
続いてカテゴリー作成画面を表示する create.php
ファイルを作成します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHP DB</title>
</head>
<body>
<h3>Categories - Create</h3>
<hr>
<form action="store.php" method="post">
ID: <input type="number" name="id"><br>
TITLE: <input type="text" name="title"><br>
<button type="submit">STORE</button>
</form>
<hr>
<a href="index.php">BACK</a>
</body>
</html>
作成したプログラムについて見ていきましょう。
create.php
ファイルはカテゴリーを作成する画面です。form
タグを使って入力フォームを定義しています。
<form action="store.php" method="post">
ID: <input type="number" name="id"><br>
TITLE: <input type="text" name="title"><br>
<button type="submit">STORE</button>
</form>
この入力フォームを使ってユーザは ID
と TITLE
の2つの項目を入力します。そのあと STORE
ボタンをクリックすると次に作成する store.php
ファイルにリクエストが送信されます。
3. カテゴリー作成処理の実装 - store.php
さいごにカテゴリー作成画面から送信されるリクエストを処理する store.php
ファイルを作成します。
<?php
$id = (string)filter_input(INPUT_POST, "id");
if ($id === "") {
error_log("Validate: id is required.");
header("Location: error.php");
exit();
}
if (filter_var($id, FILTER_VALIDATE_INT) === false) {
error_log("Validate: id is not int.");
header("Location: error.php");
exit();
}
$title = (string)filter_input(INPUT_POST, "title");
if ($title === "") {
error_log("Validate: title is required.");
header("Location: error.php");
exit();
}
if (mb_strlen($title) > 255) {
error_log("Validate: title length > 255");
header("Location: error.php");
exit();
}
try {
$dsn = "mysql:host=localhost;dbname=eldb;charset=utf8mb4";
$username = "root";
$password = "admin";
$options = [
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false
];
$pdo = new PDO($dsn, $username, $password);
$sql = "insert into categories (id, title) values (:id, :title)";
$ps = $pdo->prepare($sql);
$ps->bindValue(":id", $id, PDO::PARAM_INT);
$ps->bindValue(":title", $title, PDO::PARAM_STR);
$ps->execute();
header("Location: index.php");
} catch (PDOException $e) {
error_log("PDOException: " . $e->getMessage());
header("Location: error.php");
}
プログラムが少し長くなりましたが、先頭から順に見ていきましょう。
このプログラムでは先頭部分で以下の仕様に従って入力チェックを実装しています。
項目名 | パラメータ名 | 入力チェック |
---|---|---|
カテゴリーID | id | 必須、整数型 |
タイトル | title | 必須、最大255文字まで |
<?php
$id = (string)filter_input(INPUT_POST, "id");
if ($id === "") {
error_log("Validate: id is required.");
header("Location: error.php");
exit();
}
if (filter_var($id, FILTER_VALIDATE_INT) === false) {
error_log("Validate: id is not int.");
header("Location: error.php");
exit();
}
上記のコードではリクエストパラメータからカテゴリーID( "id"
)を取得して、必須チェックと整数型チェックを実装しています。ここでは入力チェックに違反する場合はエラー画面にリダイレクトするように実装しています。
リクエストパラメータが整数型かどうかをチェックするために
filter_var
関数を使用しています。filter_var
関数は第2引数にFILTER_VALIDATE_INT
定数を指定することで、第1引数に指定した変数が整数型かどうかを検証できます。
タイトル( "title"
)についての入力チェックも同様です。
$title = (string)filter_input(INPUT_POST, "title");
if ($title === "") {
error_log("Validate: title is required.");
header("Location: error.php");
exit();
}
if (mb_strlen($title) > 255) {
error_log("Validate: title length > 255");
header("Location: error.php");
exit();
}
ここでも入力チェックに違反する場合はエラー画面にリダイレクトするように実装しています。
ここではデータベースとのプログラミングに重点を置くため、入力チェックの実装を簡易な実装としています。実際のシステム開発においては、入力チェックに違反する場合は、入力元画面に遷移して入力エラーメッセージを表示するなど、細かな処理を実装することが多いです。
プログラムの後半部分を見てみましょう。
try {
$dsn = "mysql:host=localhost;dbname=eldb;charset=utf8mb4";
$username = "root";
$password = "admin";
$options = [
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false
];
$pdo = new PDO($dsn, $username, $password);
$sql = "insert into categories (id, title) values (:id, :title)";
$ps = $pdo->prepare($sql);
$ps->bindValue(":id", $id, PDO::PARAM_INT);
$ps->bindValue(":title", $title, PDO::PARAM_STR);
$ps->execute();
header("Location: index.php");
} catch (PDOException $e) {
error_log("PDOException: " . $e->getMessage());
header("Location: error.php");
}
ここではまずPDOインスタンスを生成してMySQLデータベースに接続しています。それからプリペアドステートメント を定義して、リクエストパラメータをプレースホルダにバインドし、insert
文を実行しています。
insert
文の実行が終わったら、header
関数を使って index.php
にリダイレクトするように実装しています。
データベースとのやりとりで例外が発生した場合は catch
ブロックの処理が実行されます。ここでは error_log
関数を使ってエラーログを出力して、エラー画面にリダイレクトするように実装しています。
動作確認
それではビルトインWebサーバを起動して、ブラウザから実行結果を確認してみましょう。
コマンドラインからビルトインWebサーバを起動します。
$ php -S localhost:8080
ブラウザから以下のURLにアクセスします。
https://〜.vfs.cloud9.ap-northeast-1.amazonaws.com/categories/index.php
上記のようにカテゴリー一覧画面が表示されることを確認します。表示された画面の下部にある CREATE
リンクをクリックしてカテゴリー作成画面( create.php
)が表示されることを確認します。
それから任意のデータを入力して新規カテゴリーレコードが作成されることを確認しましょう。
それから STORE
ボタンをクリックします。
上記のようにカテゴリー一覧画面にリダイレクトされると、作成したカテゴリーレコードを確認できるでしょう。
ターミナルからMySQLに接続すると
categories
テーブルに新規レコードが作成されていることを確認できます。