前回、データベースにデータを「保存(INSERT)」することに成功しました。
しかし、まだphpMyAdminを見ないとデータが確認できません。
今回は、保存されたデータをPHPで取得し、HTMLのリストとして画面に表示させます。
これで「ひとこと掲示板」がいよいよ完成します!
データを取る命令「SELECT」
データを取得するときは、SQLの SELECT(セレクト) 文を使います。
SELECT * FROM テーブル名
「アスタリスク(*)」は「全部のカラム(idも名前も日付も全部)」という意味です。
つまり「〇〇テーブルから、すべてのデータを持ってこい!」という命令になります。
並び順を指定する「ORDER BY」
掲示板なら、新しい投稿が上に来てほしいですよね。
そんな時は ORDER BY を付け足します。
SELECT * FROM messages ORDER BY id DESC
- ASC(アスク): 小さい順(古い順)。1, 2, 3…
- DESC(デスク): 大きい順(新しい順)。3, 2, 1…
PHPでデータを受け取る手順
PHPでデータを受け取るには、以下の3ステップを踏みます。
query(): SQLを実行する。fetchAll(): 結果をすべて「配列」として引っ張り出す。foreach: ループして1つずつ表示する。
// 1. SQLを実行
$sql = "SELECT * FROM messages ORDER BY id DESC";
$stmt = $pdo->query($sql);
// 2. 全データを配列に入れる(ここがポイント!)
$results = $stmt->fetchAll();
これで $results という変数の中に、全データが「連想配列のリスト」として入りました。
実践:掲示板を完成させよう
では、前回の「書き込み機能」と今回の「表示機能」を合体させて、1つのファイルにまとめましょう。
bbs.php という名前で作成してください。
<?php
// DB接続設定(共通)
$dsn = 'mysql:dbname=bbs_app;host=localhost;charset=utf8mb4';
$user = 'root';
$password = ''; // MAMPは 'root'
try {
$pdo = new PDO($dsn, $user, $password);
// === 送信された時(書き込み処理) ===
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = $_POST['username'];
$comment = $_POST['comment'];
// SQL作成と実行(プリペアドステートメント!)
$sql = "INSERT INTO messages (username, comment, created_at) VALUES (:username, :comment, NOW())";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':username', $username, PDO::PARAM_STR);
$stmt->bindValue(':comment', $comment, PDO::PARAM_STR);
$stmt->execute();
}
// === 常に実行(読み込み処理) ===
// 新しい順(DESC)にデータを取得
$sql = "SELECT * FROM messages ORDER BY id DESC";
$stmt = $pdo->query($sql);
// 全件取得して配列に入れる
$messages = $stmt->fetchAll();
} catch (PDOException $e) {
echo "エラー: " . $e->getMessage();
exit;
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ひとこと掲示板</title>
<style>
.post { border-bottom: 1px solid #ddd; padding: 10px; }
.info { color: #888; font-size: 0.8em; }
</style>
</head>
<body>
<h1>ひとこと掲示板</h1>
<!-- 書き込みフォーム -->
<form action="" method="post" style="background: #f4f4f4; padding: 10px;">
名前:<input type="text" name="username" required>
ひとこと:<input type="text" name="comment" required>
<button type="submit">送信</button>
</form>
<hr>
<!-- 投稿一覧 -->
<h2>投稿一覧</h2>
<?php foreach ($messages as $msg): ?>
<div class="post">
<!-- XSS対策:htmlspecialcharsを忘れずに! -->
<strong> <?= htmlspecialchars($msg['username'], ENT_QUOTES, 'UTF-8') ?> </strong>
: <?= htmlspecialchars($msg['comment'], ENT_QUOTES, 'UTF-8') ?>
<div class="info">
投稿日:<?= $msg['created_at'] ?>
</div>
</div>
<?php endforeach; ?>
</body>
</html>
解説:プログラムの流れ
- ページを開くと、まずDBに接続します。
- もし「送信」ボタンが押されていたら、
INSERTで保存します。 - その後、
SELECTで最新のデータを全件取得します。 - HTMLの下の方で、
foreachを使ってデータを1個ずつ表示します。
これで、投稿ボタンを押すと画面がリロードされ、今書いたコメントが一番上に表示されるはずです。
まとめ
- データを取得するには
SELECT * FROM テーブル名。 - 新しい順にするなら
ORDER BY id DESC。 fetchAll()で配列にしてから、foreachで表示する。- 表示するときは必ず
htmlspecialchars()を使う!
おめでとうございます!これでデータベースを使ったWebアプリの基本形が完成しました。
「書く・保存する・表示する」というサイクルは、TwitterもInstagramも基本は同じです。
次回は応用編の最終回。「PHP-8:削除と編集機能」について軽く触れて、PHP編の総まとめを行います。
間違えて投稿したメッセージを消せるようにしましょう!
📝 今日のミニテスト
クリックで答え合わせ!
Q1. データを取得するSQL「SELECT」で、新しい順(降順)に並べるためのキーワードは?
正解:DESC (デスク)
ORDER BY id DESC のように使います。逆に古い順(昇順)は ASC です。
Q2. 取得した結果を「すべての行が入った配列」として取り出すPHPのメソッドは?
正解:fetchAll()
これを使えば、あとは foreach で回すだけで一覧表示ができます。
Q3. データベースから出したデータを表示する際、必ずやるべきセキュリティ対策は?
正解:htmlspecialchars() を通す
誰かが「<script>」などを投稿している可能性があるため、表示する瞬間に無毒化するのが鉄則です。