🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

【PHP入門】動くWebアプリ開発!データベース連携で一言掲示板を作る

これまでの記事で、PHPの文法やデータベースからデータを取得して表示する方法を学びました。しかし、Webアプリケーションの本当の面白さは、ユーザーがデータを「追加」したり「削除」したり、双方向のやり取りができてこそです。この「ユーザーによるデータの操作」こそ、あらゆるWebサービスの核心と言えるでしょう。

この記事では、これまでの知識を総動員して、データベースと連携した本格的なWebアプリケーション、一言メモ掲示板を開発します。この掲示板は、メモの投稿(Create)、一覧表示(Read)、そして削除(Delete)という、Webアプリの基本となる3つの機能を備えています。少し長めのコードになりますが、これを1つのファイルにコピペして自分のサーバーで動かせば、あなただけの「動くWebアプリケーション」が完成します。プログラミングの大きな達成感を、ぜひ味わってください!

PHPを動かすための準備(開発環境)まだXAMPP「ザンプ」を構築してない方は、【PHP入門】XAMPPのダウンロードとインストール方法を徹底解説!を参照してください。 インストール後、指定されたフォルダ(`htdocs`など)にPHPファイルを置けば、準備は完了です!

1. CRUD:Webアプリケーションの基本設計

私たちが普段使っているSNSやブログ、ECサイトなどのWebアプリケーションは、基本的に4つのデータ操作で成り立っています。その頭文字をとってCRUD(クラッド)と呼ばれます。

今回はこの中から、編集(Update)を除いたC・R・Dの3つの機能を実装し、Webアプリケーション開発の第一歩を踏み出します。

2. 実践!一言メモ掲示板を開発する

それでは、早速作っていきましょう。1つのPHPファイルだけで、投稿・表示・削除のすべての機能を実現します。

ステップA: データベースとテーブルの準備

まず、メモを保存するための`memos`テーブルをデータベースに作成します。phpMyAdminなどで以下のSQLを実行してください。

CREATE TABLE memos (
  id INT AUTO_INCREMENT PRIMARY KEY,
  content VARCHAR(255) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- サンプルデータをいくつか入れておきましょう
INSERT INTO memos (content) VALUES
('PHPの勉強を始める'),
('今日の晩ごはんのメニューを考える'),
('週末の買い出しリストを作成する');

ステップB: すべての機能を実装したPHPファイル

ここからが本番です。以下のコードを`memo.php`などの名前で保存してください。データベースへの接続情報、データの追加ロジック、削除ロジック、そして表示ロジックのすべてがこの1ファイルに詰まっています。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>一言メモ掲示板</title>
    <style>
        body { font-family: sans-serif; padding: 20px; max-width: 700px; margin: auto; background-color: #f9f9f9; }
        h1, h2 { color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px; }
        .memo-form { background: #fff; padding: 20px; border-radius: 8px; margin-bottom: 30px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        textarea { width: 100%; height: 60px; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; margin-bottom: 10px; }
        button { padding: 10px 20px; border: none; background-color: #28a745; color: white; border-radius: 4px; cursor: pointer; }
        button:hover { background-color: #218838; }
        .memo-list { list-style: none; padding: 0; }
        .memo-item { background: #fff; padding: 15px; border-left: 5px solid #007bff; margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center; box-shadow: 0 2px 4px rgba(0,0,0,0.05); }
        .memo-content { flex-grow: 1; }
        .memo-date { font-size: 0.8em; color: #888; display: block; margin-top: 5px; }
        .delete-btn { background-color: #dc3545; }
        .delete-btn:hover { background-color: #c82333; }
        .error-message { color: red; font-weight: bold; }
    </style>
</head>
<body>
    <h1>一言メモ掲示板</h1>

    <?php
    // --- データベース接続情報 ---
    $db_host = 'localhost';
    $db_name = 'your_database_name';
    $db_user = 'your_username';
    $db_pass = 'your_password';

    try {
        $pdo = new PDO("mysql:host={$db_host};dbname={$db_name};charset=utf8", $db_user, $db_pass);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        // --- データ処理 (POSTリクエストがあった場合) ---
        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
            if (isset($_POST['action']) && $_POST['action'] === 'add') {
                // 【Create】メモの追加処理
                if (!empty($_POST['content'])) {
                    $stmt = $pdo->prepare("INSERT INTO memos (content) VALUES (:content)");
                    $stmt->execute([':content' => $_POST['content']]);
                }
            } elseif (isset($_POST['action']) && $_POST['action'] === 'delete') {
                // 【Delete】メモの削除処理
                if (isset($_POST['id'])) {
                    $stmt = $pdo->prepare("DELETE FROM memos WHERE id = :id");
                    $stmt->execute([':id' => $_POST['id']]);
                }
            }
            // 処理後に自身にリダイレクトして、二重投稿を防止
            header('Location: ' . $_SERVER['SCRIPT_NAME']);
            exit;
        }

        // --- データ表示 (GETリクエストの場合) ---
        // 【Read】メモの一覧を取得
        $stmt = $pdo->prepare("SELECT * FROM memos ORDER BY created_at DESC");
        $stmt->execute();
        $memos = $stmt->fetchAll(PDO::FETCH_ASSOC);

    } catch (PDOException $e) {
        echo '<div class="error-message">データベースエラー: ' . htmlspecialchars($e->getMessage()) . '</div>';
        die(); // エラー時は処理を終了
    }
    ?>

    <!-- メモ投稿フォーム -->
    <section class="memo-form">
        <h2>新しいメモを投稿</h2>
        <form action="" method="POST">
            <input type="hidden" name="action" value="add">
            <textarea name="content" required></textarea>
            <button type="submit">投稿する</button>
        </form>
    </section>

    <!-- メモ一覧表示 -->
    <section>
        <h2>メモ一覧</h2>
        <ul class="memo-list">
            <?php if ($memos): ?>
                <?php foreach ($memos as $memo): ?>
                    <li class="memo-item">
                        <div class="memo-content">
                            <?php echo htmlspecialchars($memo['content']); ?>
                            <span class="memo-date">(<?php echo $memo['created_at']; ?>)</span>
                        </div>
                        <form action="" method="POST" style="display:inline;">
                            <input type="hidden" name="action" value="delete">
                            <input type="hidden" name="id" value="<?php echo $memo['id']; ?>">
                            <button type="submit" class="delete-btn">削除</button>
                        </form>
                    </li>
                <?php endforeach; ?>
            <?php else: ?>
                <li>まだ投稿がありません。</li>
            <?php endif; ?>
        </ul>
    </section>

</body>
</html>

重要:このコードも、実行前にデータベースの接続情報をご自身の環境に合わせて書き換えるのを忘れないでください。

どうでしょうか?フォームからメモを投稿すると一覧にリアルタイムで追加され、削除ボタンを押すとそのメモが消える、という一連の動作が確認できたはずです。これがWebアプリケーション開発の基本となるCRUD操作(今回はCRD)です。

3. コードの解説と重要なポイント

この1ファイルのコードには、重要なテクニックがいくつか詰まっています。

1ファイルで全てを処理する仕組み

このアプリは、データの送信(POST)とページの表示(GET)を同じファイルで扱っています。`if ($_SERVER['REQUEST_METHOD'] === 'POST')`で、「フォームが送信されたとき」の処理をまとめて行っています。追加も削除もPOSTリクエストとして受け取り、処理が終わったら自分自身にリダイレクトさせています。これは**Post/Redirect/Get (PRG) パターン**と呼ばれるテクニックで、ブラウザの更新ボタンを押した際に同じデータが何度も送信されてしまう「二重投稿」を防ぐ効果があります。

hiddenタイプのinputタグの活用

投稿フォームと削除ボタンは、どちらも同じファイルにPOSTでデータを送ります。どちらの処理をしたいか区別するために、`<input type="hidden">`を使っています。

<!-- 投稿フォーム側 -->
<input type="hidden" name="action" value="add">

<!-- 削除フォーム側 -->
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?php echo $memo['id']; ?>">

このように、画面には表示されない隠しデータとして「`action`(どんな操作か)」や「`id`(どのメモを対象にするか)」を一緒に送信することで、PHP側は受け取ったデータを見て適切な処理(追加 or 削除)を実行できるのです。

4. まとめと次のステップ

お疲れ様でした!今回は、データベースと連携し、データの作成(Create)、読み込み(Read)、削除(Delete)の機能を持つ、動的なWebアプリケーション「一言メモ掲示板」を作成しました。自分の書いたコードがブラウザ上で実際に「アプリ」として動く体験は、大きな自信に繋がったのではないでしょうか。

このCRUDの考え方は、あらゆるWebアプリケーションの基礎となります。ここからさらに、

といった形で機能を拡張していくことができます。ぜひ、今回の掲示板をベースにして、あなただけのオリジナルアプリケーション開発に挑戦してみてください!