データベースにデータを保存したら、次はそのデータを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サイトを構築する上で最も基本的ながら、強力なテクニックです。ぜひマスターしてください。