PHPで詳細ページを作成!データベースから取得したデータを表示する方法

URLからIDを受け取り、そのIDを使ってデータベースから特定のレコードを取得する準備が整いました。最後のステップは、取得したデータをHTMLに埋め込み、ユーザーに見やすい「詳細ページ」として完成させることです。

この記事では、PDOで取得した一行分のデータを、PHPのechohtmlspecialchars()を使い、安全にWebページに表示する具体的な方法を解説します。


目次

1. 1件のデータを取得するfetch()メソッドの確認

まず、特定のIDを持つレコード1件だけを取得する流れをおさらいしましょう。

  1. prepare()WHERE id = ?という条件付きのSQL文を準備する。
  2. execute([$id])で、安全な形でIDをSQL文に渡して実行する。
  3. fetch(PDO::FETCH_ASSOC)で、結果セットから最初の1行だけを連想配列として取得する。

この結果、変数(例: $review)には、以下のような単一の連想配列が格納されます。

// $review の中身のイメージ
[
    'id' => 5,
    'book_title' => 'SQL実践入門',
    'rating' => 4,
    'review_text' => "サンプルが多くて分かりやすい。\n実践的な内容だった。"
]

この連想配列のキー(book_titleなど)を使って、各データにアクセスします。

レコードが見つからなかった場合の考慮

もしURLで指定されたID(例: id=999)がデータベースに存在しなかった場合、fetch()メソッドはレコードを見つけられず、**false**を返します。この「データが存在しない」というケースを考慮しないと、エラーの原因になります。


2. 取得したデータをHTMLに表示する

取得した連想配列の値をHTMLに表示するには、echoを使い、キーを指定して値を取り出します。

基本の書き方: echo $review['book_title'];

そして、セキュリティの観点から絶対に忘れてはならないのが、htmlspecialchars()によるエスケープ処理です。ユーザーが入力したデータだけでなく、データベースから取得したデータであっても、画面に出力する際は必ずこの処理を行い、XSS(クロスサイトスクリプティング)攻撃を防ぎましょう。

安全な書き方: echo htmlspecialchars($review['book_title'], ENT_QUOTES, 'UTF-8');


3. 完成版コード:動的な詳細ページの作成

それでは、これまでの知識を総動員して、IDのバリデーションからデータの取得、表示、そして「データが見つからなかった場合」の処理までを実装した、完全な詳細ページのサンプルコードを見てみましょう。

detail.phpのサンプルコード:

<?php
// --- データベース接続設定 ---
$dsn = 'mysql:host=localhost;dbname=my_first_db;charset=utf8mb4';
$user = 'root';
$password = 'root'; // ご自身の環境に合わせて変更してください

// --- 初期化 ---
$review = null;
$error_message = '';

try {
    // --- IDのバリデーション ---
    if (empty($_GET['id']) || !ctype_digit($_GET['id'])) {
        throw new Exception('IDが不正です。');
    }
    $id = (int)$_GET['id'];

    // --- データベース処理 ---
    $pdo = new PDO($dsn, $user, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    $sql = "SELECT * FROM reviews WHERE id = ?";
    $stmt = $pdo->prepare($sql);
    $stmt->execute([$id]);
    $review = $stmt->fetch(PDO::FETCH_ASSOC);

    // --- レコード存在チェック ---
    if (!$review) {
        throw new Exception('指定されたレビューは見つかりませんでした。');
    }

} catch (Exception $e) {
    // エラーメッセージを$error_messageに格納
    $error_message = $e->getMessage();
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>読書レビュー詳細</title>
</head>
<body>

    <?php if ($error_message): ?>
        <h1>エラー</h1>
        <p><?php echo htmlspecialchars($error_message, ENT_QUOTES, 'UTF-8'); ?></p>
        <a href="list.php">一覧に戻る</a>
    <?php else: ?>
        <h1><?php echo htmlspecialchars($review['book_title'], ENT_QUOTES, 'UTF-8'); ?></h1>
        
        <dl>
            <dt>評価:</dt>
            <dd><?php echo htmlspecialchars($review['rating'], ENT_QUOTES, 'UTF-8'); ?> / 5</dd>
            
            <dt>感想:</dt>
            <dd><?php echo nl2br(htmlspecialchars($review['review_text'], ENT_QUOTES, 'UTF-8')); ?></dd>
            
            <dt>登録日時:</dt>
            <dd><?php echo htmlspecialchars($review['created_at'], ENT_QUOTES, 'UTF-8'); ?></dd>
        </dl>
        
        <a href="list.php">一覧に戻る</a>
    <?php endif; ?>

</body>
</html>

コードのポイント:

  • エラーハンドリング: try...catchブロックを使い、IDの不正やデータが見つからない場合のエラーメッセージを$error_message変数に格納しています。
  • 条件付きレンダリング: PHPのif/else構文を使い、$error_messageに何か入っている(=エラーがあった)場合はエラー表示を、そうでなければ(=正常に$reviewが取得できた)詳細情報を表示するように、HTMLの出力を切り替えています。
  • 安全な出力: 表示するすべての動的データ($error_message$reviewの各要素)は、htmlspecialchars()でエスケープしています。

まとめ

  • fetch(PDO::FETCH_ASSOC)で取得した単一レコード(連想配列)から、キー(カラム名)を指定して値を取り出す。
  • fetch()falseを返す(=データが見つからない)場合に備え、エラー処理を実装する。
  • PHPのif/else構文とHTMLを組み合わせることで、正常時とエラー時で表示内容を動的に切り替えることができる。
  • データベースから取得した値であっても、画面に出力する際は必ずhtmlspecialchars()を使う。

この一連の処理は、Webアプリケーションにおける最も基本的ながら、最も重要なデータ表示のパターンです。この構造をマスターすれば、どんなデータでも安全に詳細ページとして表示できるようになります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次