フォームデータの検証、データ型の変換といった準備を経て、いよいよ最終ステップである「データベースへのデータ登録」です。この処理は、ユーザーの情報をアプリケーションに「記憶」させる、動的なWebサイトの心臓部と言えます。
最も重要なのは、この登録処理を安全に行うことです。悪意のあるデータがデータベースに登録されたり、システムを攻撃されたりするのを防ぐため、PHPではPDOのプリペアドステートメントを用いるのが現代の常識です。
この記事では、これまでの知識を総動員し、フォームから受け取ったデータを安全にデータベースへINSERT
する、完成版のPHPスクリプトを解説します。
1. INSERT
文とプレースホルダのおさらい
まず、新しいデータを登録するためのSQL文INSERT
と、セキュリティの要であるプレースホルダの関係を確認しましょう。
変動する値(ユーザーの入力内容)は、SQL文に直接埋め込むのではなく、すべて?
(プレースホルダ)に置き換えます。これにより、データベースは命令(SQL)と値(データ)を明確に区別でき、SQLインジェクション攻撃を根本的に防ぐことができます。
prepare()
で準備するSQL文の例:
<?php
// 登録するデータ項目に対応する数の?を用意する
$sql = "INSERT INTO reviews (book_title, rating, review_text) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
?>
2. 複数のプレースホルダに値を渡して実行する
prepare()
で準備したSQL文の?
に、実際の値を渡して実行します。この「値を渡す(バインドする)」方法には、主に2つの書き方があります。
方法1(推奨): execute()
に配列を渡す
最もシンプルで、現代のPHPで広く使われている方法です。execute()
メソッドの引数に、?
の順番通りに値を格納した配列を渡します。
<?php
// $book_title, $rating_int, $review_text はフォームから受け取り、
// バリデーションと型キャストが済んだ変数
$stmt->execute([$book_title, $rating_int, $review_text]);
?>
この一行で、安全な値のバインドとSQLの実行が完了します。コードが簡潔で、非常に分かりやすいのが特徴です。
方法2(明示的): bindValue()
で個別に指定する
bindValue()
メソッドを使い、各プレースホルダに値を一つずつ、より明示的に紐付ける方法もあります。
<?php
// 1番目の?に$book_titleを文字列としてバインド
$stmt->bindValue(1, $book_title, PDO::PARAM_STR);
// 2番目の?に$rating_intを整数としてバインド
$stmt->bindValue(2, $rating_int, PDO::PARAM_INT);
// 3番目の?に$review_textを文字列としてバインド
$stmt->bindValue(3, $review_text, PDO::PARAM_STR);
$stmt->execute(); // executeの引数は空にする
?>
この方法は、値のデータ型(PDO::PARAM_STR
やPDO::PARAM_INT
)を厳密に指定したい場合に有効です。
3. 完成版コード:フォームデータ登録処理のすべて
それでは、バリデーションから型変換、そしてデータベース登録までの一連の流れを実装した、完全なadd.php
のコードです。このスクリプトは、これまでの学習内容の集大成となります。
add.php
のサンプルコード:
<?php
// --- データベース接続設定 ---
$dsn = 'mysql:host=localhost;dbname=my_first_db;charset=utf8mb4';
$user = 'root';
$password = 'root'; // ご自身の環境に合わせて変更
// --- フォームからのPOST送信でのみ処理を実行 ---
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
exit('不正なリクエストです。');
}
try {
// --- 1. バリデーション ---
if (empty($_POST['book_title'])) {
throw new Exception('書籍名は必須です。');
}
if (empty($_POST['rating']) || !ctype_digit($_POST['rating'])) {
throw new Exception('評価は半角数字で入力してください。');
}
// --- 2. データを変数に格納 & 型キャスト ---
$book_title = $_POST['book_title'];
$rating = (int)$_POST['rating']; // 整数型に変換
$review_text = $_POST['review_text'];
// --- 3. データベースへの接続 ---
$pdo = new PDO($dsn, $user, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
// --- 4. INSERT文の準備と実行 ---
$sql = "INSERT INTO reviews (book_title, rating, review_text) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
// execute()の引数に、プレースホルダに渡す値を配列で指定
$stmt->execute([$book_title, $rating, $review_text]);
// --- 5. 成功メッセージの表示 ---
echo "レビューの登録が完了しました。";
} catch (Exception $e) {
// --- 6. エラー発生時の処理 ---
echo "エラー発生: " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
} finally {
// --- 7. データベース接続の解放 ---
// finallyブロックは、tryやcatchの処理が終わった後、必ず実行される
$pdo = null;
}
?>
<br>
<a href="form.html">入力フォームに戻る</a>
まとめ
今回は、PHPアプリケーションの根幹となる、安全なデータベース登録処理の全貌を学びました。
INSERT
文では、変動する値を必ずプレースホルダ(?
)にする。prepare()
でSQLを準備し、execute()
に配列を渡して安全に実行する。- **「バリデーション → 型キャスト → DB接続 → prepare → execute」**という一連の流れが、堅牢な登録処理の基本形。
try...catch
構文で処理全体を囲むことで、予期せぬエラーにも適切に対処できる。
このパターンは、あらゆるデータの登録処理に応用できる、非常に重要なものです。この安全な「型」を身につけて、信頼性の高いWebアプリケーションを構築していきましょう。