【PHP応用-3】保存したデータを画面に出そう!SELECT文とforeachの連携技

前回、データベースにデータを「保存(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ステップを踏みます。

  1. query() SQLを実行する。
  2. fetchAll() 結果をすべて「配列」として引っ張り出す。
  3. 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>

解説:プログラムの流れ

  1. ページを開くと、まずDBに接続します。
  2. もし「送信」ボタンが押されていたら、INSERT で保存します。
  3. その後、SELECT で最新のデータを全件取得します。
  4. 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>」などを投稿している可能性があるため、表示する瞬間に無毒化するのが鉄則です。

タイトルとURLをコピーしました