PHPでデータベースのデータを取得し、HTMLのテーブルで一覧表示する方法

データベースにデータを保存したら、次はそのデータをWebページに一覧として表示させたくなりますよね。ブログの記事一覧や、ECサイトの商品リスト、SNSの投稿履歴など、Webアプリケーションの中核となる機能です。

この処理は、**「1. データベースから全データを取得」し、「2. HTMLのテーブル構造を作成」し、「3. 取得したデータでテーブルの中身を動的に生成」**するという流れで行います。

この記事では、PHP(PDO)を使ってMySQLから取得した全レコードを、HTMLのテーブル形式で安全に表示する具体的な手順を解説します。


目次

1. データベースから全データを取得する

まず、PHPを使って表示したいテーブルから全てのレコードを取得します。SELECT * FROM テーブル名 というSQL文をPDOのprepare/executeで実行し、fetchAll(PDO::FETCH_ASSOC)メソッドで結果を全て配列として受け取ります。

<?php
// (データベース接続処理... $pdoに接続済みPDOオブジェクトが入っていると仮定)

// 1. SQL文を準備
$sql = "SELECT * FROM reviews ORDER BY created_at DESC"; // ORDER BYで新しい順に並び替え
$stmt = $pdo->prepare($sql);

// 2. SQLを実行
$stmt->execute();

// 3. 結果を全件取得して、多次元配列に格納
$reviews = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>

この時点で、変数$reviewsには、reviewsテーブルの全データが、以下のような多次元配列の形で格納されています。

// $reviews の中身のイメージ
[
    ['id' => 2, 'book_title' => 'SQL実践入門', 'rating' => 4, ...],
    ['id' => 1, 'book_title' => 'PHP入門', 'rating' => 5, ...],
]

2. foreachループでテーブルの行を生成する

次に、HTMLの<table>タグで表の枠組みを作り、取得したデータを表示していきます。多次元配列の各要素を順番に取り出して処理するには、foreachループが最適です。

foreach ($reviews as $review)と書くことで、$reviews配列の中のレコード(一行分のデータ配列)が、ループの各回で順番に$reviewという変数に代入されます。

ループの中で<tr>(テーブルの行)と<td>(テーブルのセル)タグを生成し、$review['カラム名']の形で各データを配置していきます。


3. 完成版コード:データベースの内容を一覧表示する

それでは、データベース接続からHTMLの表示までをまとめた、完全なサンプルコードを見てみましょう。

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

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

try {
    // データベースへの接続
    $pdo = new PDO($dsn, $user, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

    // SQL文を準備
    $sql = "SELECT id, book_title, rating, review_text FROM reviews ORDER BY created_at DESC";
    $stmt = $pdo->prepare($sql);
    $stmt->execute();
    $reviews = $stmt->fetchAll(PDO::FETCH_ASSOC);

} catch (PDOException $e) {
    // エラー発生時の処理
    echo "接続失敗: " . $e->getMessage();
    exit();
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>読書レビュー一覧</title>
    <style>
        table { width: 100%; border-collapse: collapse; }
        th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
        th { background-color: #f2f2f2; }
    </style>
</head>
<body>
    <h1>読書レビュー一覧</h1>
    <table>
        <thead>
            <tr>
                <th>書籍名</th>
                <th>評価 (5段階)</th>
                <th>感想</th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($reviews as $review): ?>
                <tr>
                    <td><?php echo htmlspecialchars($review['book_title'], ENT_QUOTES, 'UTF-8'); ?></td>
                    <td><?php echo htmlspecialchars($review['rating'], ENT_QUOTES, 'UTF-8'); ?></td>
                    <td><?php echo nl2br(htmlspecialchars($review['review_text'], ENT_QUOTES, 'UTF-8')); ?></td>
                </tr>
            <?php endforeach; ?>
        </tbody>
    </table>
</body>
</html>

重要なポイント:

  • foreachループを使って、配列$reviewsの要素の数だけ<tr>タグを動的に生成しています。
  • echoでHTML内に変数の内容を出力する際は、XSS攻撃を防ぐため、必ずhtmlspecialchars()でエスケープ処理を行っています。
  • 感想(review_text)は改行を反映させるためにnl2br()も併用しています。

(応用) レコードが存在しない場合の処理

もしデータベースに1件もデータが登録されていなかった場合、fetchAll()は空の配列を返します。その場合、上のコードではテーブルの見出しだけが表示され、中身が空の状態になります。

より親切な表示にするために、$reviewsが空かどうかをif文で判定する処理を追加しましょう。

        <tbody>
            <?php if (empty($reviews)): ?>
                <tr>
                    <td colspan="3">まだレビューはありません。</td>
                </tr>
            <?php else: ?>
                <?php foreach ($reviews as $review): ?>
                    <tr>
                        <td><?php echo htmlspecialchars($review['book_title'], ENT_QUOTES, 'UTF-8'); ?></td>
                        <td><?php echo htmlspecialchars($review['rating'], ENT_QUOTES, 'UTF-8'); ?></td>
                        <td><?php echo nl2br(htmlspecialchars($review['review_text'], ENT_QUOTES, 'UTF-8')); ?></td>
                    </tr>
                <?php endforeach; ?>
            <?php endif; ?>
        </tbody>

empty()関数で配列が空かどうかをチェックし、空の場合は「まだレビューはありません。」というメッセージを表示するようにしました。

まとめ

  • データベースから複数のレコードを取得するにはfetchAll(PDO::FETCH_ASSOC)が便利。
  • 取得した配列データはforeachループで順番に処理する。
  • ループの中で<tr><td>タグを生成することで、動的なHTMLテーブルを作成できる。
  • 出力するすべてのデータはhtmlspecialchars()でエスケープすることを徹底する。

この「取得 → ループ → 表示」というパターンは、PHPで動的なWebサイトを構築する上で最も基本的ながら、強力なテクニックです。ぜひマスターしてください。

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

この記事を書いた人

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

目次