PHPとMySQLを使ってディスカッションフォーラムを作成する方法

カバーイメージ

PHPとMySQLを使ってディスカッションフォーラムを作りたい方は、正しい場所に来ています。このガイドでは、テキストベースの説明を使って基本的なディスカッションフォーラムを作る簡単なステップを説明しようと思います。

サーバー環境のセットアップ

ApachePHPMySQLがサーバーにインストールされていることを確認してください。

Linux UbuntuシステムにApache、PHP、MySQLをインストールするには、次のステップで行ってください。ターミナルを開いて、以下のコマンドを実行します:
パッケージリストを更新

sudo apt update

Apache(HTTPサーバー)をインストール

sudo apt install apache2

インストール後、Apacheは自動的に起動するはずです。そのステータスは以下で確認できます:

sudo systemctl status apache2

MySQL(データベースサーバー)をインストール
MySQLをインストールするには、mysql-serverパッケージを使用できます:

sudo apt install mysql-server

インストール中に、MySQLのrootパスワード設定が求められます。

インストール後、以下を実行してMySQLのセキュリティ設定を行えます:

sudo mysql_secure_installation

プロンプトに従ってMySQLのセキュリティ設定を行ってください。

PHPをインストール
PHPと一般的にWeb開発で使用されるPHPモジュールをインストールします:

sudo apt install php libapache2-mod-php php-mysql
  • ApacheでPHPを使用するように設定する
    ApacheをPHPファイルの扱えるようにするために、phpモジュールを有効にしてApacheを再起動する必要があります:
sudo a2enmod php
sudo systemctl restart apache2

セットアップをテスト
Apache-PHPのセットアップをテストするために、簡単なPHPファイルを作成します。NanoやVimなどのテキストエディタを使用できます:

sudo nano /var/www/html/info.php

ファイルに以下の内容を追加し、保存して終了します:

<?php phpinfo(); ?>

これで、WebブラウザでこのPHP情報ファイルにアクセスできます。Webブラウザを開き、次へアクセスしてください:

http://your_server_ip/info.php

データベースのセットアップ:

フォーラム用のMySQLデータベースを作成します。
フォーラムデータを格納するために必要なテーブル(例:Users、Threads、Posts)を設計します。

データベースの作成:

MySQLにログイン後、新しいデータベースを作成できます。forum_databaseを希望のデータベース名に置き換えてください:

CREATE DATABASE forum_database;

データベースを作成した後、使用中のデータベースとして選択します:

USE forum_database;

これで、フォーラム用の必要なテーブルを作成できます。以下は、Users、Threads、Postsのテーブルを作成する例です:

Usersテーブル:

CREATE TABLE users (
    user_id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(255) NOT NULL,
    password VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL,
    registration_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    -- 必要に応じて他のユーザー関連のフィールドを追加
);

Threadsテーブル:

CREATE TABLE threads (
    thread_id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    -- 必要に応じて他のスレッド関連のフィールドを追加
    FOREIGN KEY (user_id) REFERENCES users(user_id)
);

Postsテーブル:

CREATE TABLE posts (
    post_id INT AUTO_INCREMENT PRIMARY KEY,
    thread_id INT NOT NULL,
    user_id INT NOT NULL,
    content TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    -- 必要に応じて他の投稿関連のフィールドを追加
    FOREIGN KEY (thread_id) REFERENCES threads(thread_id),
    FOREIGN KEY (user_id) REFERENCES users(user_id)
);

フォーラムの要件に応じて、カテゴリ、ユーザーロール、投稿のいいね/いいねじゃないなどの追加テーブルが必要になるかもしれません。特定のニーズに合わせてテーブル設計をカスタマイズしてください。

  1. ユーザー認証 登録フォームを作成する: ユーザーネーム、メールアドレス、パスワードなど、必要なユーザー情報を含むHTMLフォームを設計します。

PHPフォーム処理:
フォームの提出を処理するPHPスクリプトを作成します。
ユーザー入力を検証して、要件を満たしていることを確認します(例:有効なメールアドレス、強力なパスワード)。
SQLインジェクションやXSS攻撃を防ぐために、ユーザー入力をサニタイズします。

PHPのpassword_hash()関数を使ってユーザーのパスワードを安全にハッシュ化し、データベースに格納します。

$password = $_POST['password'];
$hashed_password = password_hash($password, PASSWORD_DEFAULT);

データベースへの挿入:
データベースにユーザー情報(ハッシュ化されたパスワードを含む)を挿入します。

// データベース接続が既に確立されていることを前提としています
$sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$username, $email, $hashed_password]);

ログインフォームを作成する:
ユーザーネーム/メールアドレスとパスワード用のフィールドを含むHTMLフォームを設計します。

パスワード検証:
データベースから、ユーザーのユーザーネームまたはメールアドレスに関連付けられたハッシュ化されたパスワードを取得します。

// データベース接続が既に確立されていることを前提としています
$sql = "SELECT user_id, username, password FROM users WHERE username = ? OR email = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$input, $input]); // $inputは入力されたユーザーネーム/メールアドレス
$user = $stmt->fetch(PDO::FETCH_ASSOC);

パスワードチェック:
password_verify()を使用して、入力されたパスワードが格納されたハッシュ化パスワードと一致するかどうかをチェックします。

if ($user && password_verify($input_password, $user['password'])) {
    // パスワードが正しい
    // セッションを開始し、ユーザーをログインさせる
    session_start();
    $_SESSION['user_id'] = $user['user_id'];
    $_SESSION['username'] = $user['username'];
    // 保護されたページにリダイレクトする
    header("Location: dashboard.php");
    exit();
} else {
    // パスワードが間違っている、エラーメッセージを表示する
    $error = "無効なユーザーネーム/メールまたはパスワード";
}
  1. スレッドの作成 スレッドのタイトルとコンテンツのフィールドを含むHTMLフォームを設計します。こちらはシンプルな例です:
<form method="POST" action="process_thread.php">
    <label for="title">スレッドタイトル:</label>
    <input type="text" name="title" id="title" required>

    <label for="content">スレッド内容:</label>
    <textarea name="content" id="content" rows="4" required></textarea>

    <input type="submit" value="スレッドを作成">
</form>

このフォームは、ユーザーが提出するとprocess_thread.phpというPHPスクリプトにPOSTリクエストを送ります。

フォームの提出を処理するPHPスクリプト(process_thread.php)を作成します。このスクリプトでは、ユーザーの入力を検証し、新しいスレッドデータをデータベースに保存します。

<?php
session_start();

// ユーザーがログインしているかチェックします。認証ロジックをここに実装してください。
if (!isset($_SESSION['user_id'])) {
    // ログインページにリダイレクトするかエラーメッセージを表示します。
    header("Location: login.php");
    exit();
}

// データベース接続コードをインクルードします。
include_once("db_connect.php");

// フォームからスレッドデータを取得します。
$title = $_POST['title'];
$content = $_POST['content'];
$user_id = $_SESSION['user_id']; // セッションからユーザーIDを取得します。

// ユーザー入力を検証します(必要に応じてさらに検証を追加してください)。
if (empty($title) || empty($content)) {
    // 検証エラーを扱い、フォームにリダイレクトします。
    header("Location: new_thread.php?error=全てのフィールドを埋めてください");
    exit();
}

// 新しいスレッドをデータベースに挿入します。
$sql = "INSERT INTO threads (user_id, title, content, created_at) VALUES (?, ?, ?, NOW())";
$stmt = $pdo->prepare($sql);
$result = $stmt->execute([$user_id, $title, $content]);

if ($result) {
    // 挿入が成功した後、スレッドまたはフォーラムページにリダイレクトします。
    header("Location: forum.php");
    exit();
} else {
    // データベースエラーを扱い、フォームにリダイレクトします。
    header("Location: new_thread.php?error=スレッドの作成に失敗しました");
    exit();
}
  1. 返信の投稿 ユーザーが返信を入力できるテキストエリアを含むHTMLフォームを設計します。こちらはシンプルな例です:
<form method="POST" action="process_reply.php">
    <textarea name="content" rows="4" required></textarea>
    <input type="hidden" name="thread_id" value="THREAD_ID_HERE">
    <input type="submit" value="返信を投稿">
</form>

フォームの提出を処理するPHPスクリプト(process_reply.php)を作成します。このスクリプトでは、ユーザーの入力を検証し、新しい投稿データをデータベースに保存し、適切なスレッドに関連付けます。

<?php
session_start();

// ユーザーがログインしているかチェックします。認証ロジックをここに実装してください。
if (!isset($_SESSION['user_id'])) {
    // ログインページにリダイレクトするかエラーメッセージを表示します。
    header("Location: login.php");
    exit();
}

// データベース接続コードをインクルードします。
include_once("db_connect.php");

// フォームから投稿データを取得します。
$content = $_POST['content'];
$user_id = $_SESSION['user_id']; // セッションからユーザーIDを取得します。
$thread_id = $_POST['thread_id']; // フォームの非表示フィールドからスレッドIDを取得します。

// ユーザー入力を検証します(必要に応じてさらに検証を追加してください)。
if (empty($content)) {
    // 検証エラーを扱い、フォームにリダイレクトします。
    header("Location: reply.php?thread_id=$thread_id&error=有効な返信を入力してください");
    exit();
}

// 新しい投稿をデータベースに挿入します。
$sql = "INSERT INTO posts (thread_id, user_id, content, created_at) VALUES (?, ?, ?, NOW())";
$stmt = $pdo->prepare($sql);
$result = $stmt->execute([$thread_id, $user_id, $content]);

if ($result) {
    // 投稿作成が成功した後、スレッドページにリダイレクトします。
    header("Location: thread.php?thread_id=$thread_id");
    exit();
} else {
    // データベースエラーを扱い、フォームにリダイレクトします。
    header("Location: reply.php?thread_id=$thread_id&error=投稿の作成に失敗しました");
    exit();
}
  1. 投稿の編集と削除 投稿表示のテンプレートに、各投稿に「編集」と「削除」のリンク/ボタンを追加します。これらのオプションは、現在ログインしているユーザーが作成した投稿に対してのみ表示します。

投稿を表示するためのHTML例:

<div class="post">
    <p>ここに投稿内容...</p>

    <?php if ($post['user_id'] === $_SESSION['user_id']): ?>
        <a href="edit_post.php?post_id=<?php echo $post['post_id']; ?>">編集</a>
        <a href="delete_post.php?post_id=<?php echo $post['post_id']; ?>">削除</a>
    <?php endif; ?>
</div>

ユーザーが自分の投稿

こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/puratabla/how-to-create-a-discussion-forum-using-php-and-mysql-33dm