こんにちは、MIO webデザインです。
第3回に引き続き、今日も『WordPressのようなコメント管理システムを作ってみよう』と思います!
- 対象者
- PHPの基礎がわかる人
- phpMyAdminの使い方がわかる人
第1回目では、データベース情報を定義するdb_info.php・入力されたコメントをデータベースに保存するsave_comment.phpを。
第2回目では、コメントの操作を行うdashboard.php(未完成)・dashboard.phpにアクセスするためのlogin.php・dashboard.phpからログアウトするためのlogout.phpを。
第3回目では、いただいたコメント一覧として表示するdashboard.php(完成)・コメントを編集するupdate.php・コメントを削除するdelete.phpを作成しました。
今回は前回に引き続き、残る2つのコメント操作の機能を実装していきます。
実装するのは、『承認機能』・『返信機能』です。
これから作っていくもの
改めまして、簡易コメント管理システム『ふらこめ(necofly comment system)』制作シリーズ第4回です!
WordPressのコメント管理機能をイメージしてくれるとありがたいです。
『ふらこめ』で実装する機能は以下の通り。
- ふらこめで実装する機能
- コメントの受付
- 管理画面でのコメント管理
- コメントの承認・削除・編集・返信機能
- 管理画面へのログイン機能
- 新規管理アカウント取得機能
ざっとこんな感じです!
コメント欄からコメントを受け付けられるのはもちろんのこと、コメントの管理画面も欲しいところですね。
ただ見る人全員が好き勝手管理できたら大変なので、ログイン機能も設置。ついでに新規管理アカウント取得(サインアップ)機能も作ってしまいましょう。

最終的には下記のようなファイル構造になります。
hura_come
├── admin
│ ├── dashboard.php
│ ├── delete.php
│ ├── display.php
│ ├── login.php
│ ├── logout.php
│ ├── reply.php
│ ├── signup.php
│ └── update.php
├── css
│ └── style.css
├── db_info
│ └── db_info.php
├── images
│ └── logo.jpg
└── save_comment.php
では早速作っていきましょう!
今回作るもの – 『承認・返信機能』
dashboard.php上では参照・編集・削除・承認・返信ができるようにしていくと、以前説明しました。参照・編集・削除機能は前回作りましたので、残るは承認機能と返信機能です。
返信機能はともかく、承認機能と聞くとパッとわかりませんね。

save_comment.phpで投稿されたコメントはデータベースに保存され、管理画面であるdashboard.phpで初めて出力されます。管理者権限を持つユーザーならコメントを確認できますが、これでは肝心のユーザーがコメントを確認できません。
そこで、save_comment.php上でもコメントが表示されるように、新たにプログラムを作らなくてはなりません。

ここである種の疑問が生まれます。
save_comment.phpでも、dashboard.phpと同じコードでコメントを表示させたらいいのではないのか?
確かにdashboard.phpのように、寄せらたコメントを全て表示させるのも1つの手です。
しかし、もしかしたら読む人が気分を害するようなコメントも、中にはあるかもしれません。スパムコメントを公の場に表示するわけにはいきません。
ですので、一度管理画面でコメントを確認し、問題なければコメントの表示を承認する、というフローが必要です。
承認ボタンが押されたら、save_comment.php上に承認されたコメントだけを出力する。
それが承認機能です。
- 今回実装する機能
- 承認されたコメントだけsave_comment.phpで表示する『承認機能』
- コメントに返信する『返信機能』
今回新たに作成するファイルは2つ。『display.php』と『reply.php』です。
下記を参考に2つのファイルを配置しましょう。
hura_come
├── admin
│ ├── dashboard.php
│ ├── delete.php
│ ├── display.php
│ ├── login.php
│ ├── logout.php
│ ├── reply.php
│ └── update.php
├── css
│ └── style.css
├── db_info
│ └── db_info.php
└── save_comment.php
ではdisplay.phpから作っていきましょう。
display.phpの作成
全体のコード

<?php
session_start();
session_regenerate_id(true);
//エラー処理
if(!isset($_SESSION['id'])){
header('Location:login.php');
exit();
} else {
echo '<div class="top_bar"><p>こんにちは! ' . $_SESSION['email'] .'さん <a href="logout.php" class="logout_button">ログアウト</a></p></div>';
}
require '../db_info/db_info.php';
//idを取得
$comment_id = $_GET['id'];
if(isset($_POST["display"])){
try{
$display = true;
//データベース接続
$dbh = new PDO(
'mysql:host=' . $host . '; dbname=' . $db_name . '; charset=utf8',
$user,
$pass,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
)
);
//SQL操作
$sql = 'UPDATE com_table SET display=? WHERE id = ?';
$data[] = $display;
$data[] = $comment_id;
$stmt = $dbh->prepare($sql);
$stmt->execute($data);
//接続解除
$dbh = null;
header('Location:dashboard.php');
exit();
}catch(PDOException $e){
echo '<div class="server_error">現在サーバーエラーが発生しています。</div>';
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>コメント承認ページ</title>
<meta name="viewport" content="width=1000">
<meta name="robots" content="noindex,nofollow">
<link rel="stylesheet" type="text/css" href="../css/style.css">
</head>
<body>
<section class="wrap ww">
<form action="display.php?id=<?php echo $comment_id; ?>" method="post" class="comment_form">
<label>コメントを承認しますか?</label>
<input type="submit" name="display" value="承認">
</form>
<a href="dashboard.php" class="go_home">戻る</a>
</section>
</body>
</html>
前回作ったdelete.phpと同じく、『承認ボタン』が押されたら処理が実行されるプログラムです。
display.phpは下記のように配置してください。
hura_come
├── admin
│ ├── dashboard.php
│ ├── delete.php
│ ├── display.php
│ ├── login.php
│ ├── logout.php
│ └── update.php
├── css
│ └── style.css
├── db_info
│ └── db_info.php
└── save_comment.php
では細かく見ていきましょう。
HTMLを記述
ますはHTMLから見ていきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>コメント承認ページ</title>
<meta name="viewport" content="width=1000">
<meta name="robots" content="noindex,nofollow">
<link rel="stylesheet" type="text/css" href="../css/style.css">
</head>
<body>
<section class="wrap ww">
<form action="display.php?id=<?php echo $comment_id; ?>" method="post" class="comment_form">
<label>コメントを承認しますか?</label>
<input type="submit" name="display" value="承認">
</form>
<a href="dashboard.php" class="go_home">戻る</a>
</section>
</body>
</html>
色々書いていますが、重要なのはform部分です。
<form action="display.php?id=<?php echo $comment_id; ?>" method="post" class="comment_form">
<label>コメントを承認しますか?</label>
<input type="submit" name="display" value="承認">
</form>
同一ファイル内で処理を行うので、データの受け渡し先はdisplay.phpです。ただし、URLパラメータとしてidを付与するのを忘れてはいけません。
submitボタンにはdisplayと、name属性を与えます。
不正アクセス対策・db_info.phpの呼び出し・idの取得
PHPの部分に移ります。
session_start();
session_regenerate_id(true);
//エラー処理
if(!isset($_SESSION['id'])){
header('Location:login.php');
exit();
} else {
echo '<div class="top_bar"><p>こんにちは! ' . $_SESSION['email'] .'さん <a href="logout.php" class="logout_button">ログアウト</a></p></div>';
}
require '../db_info/db_info.php';
//idを取得
$comment_id = $_GET['id'];
この部分は前回のupdate.phpとdelete.phpと同じですね。
簡単に説明だけさせていただきます。
- このコードでしていること
- セッションの開始
- 新規セッションIDの取得
- 不正アクセス対策
- db_info.phpの呼び出し
- 編集したいデータのidを取得
承認ボタンが押されたら処理を開始
if(isset($_POST["display"])){
try{
//中略
}catch(PDOException $e){
echo '<div class="server_error">現在サーバーエラーが発生しています。</div>';
}
}
displayに値がある、つまり承認ボタンが押されたら処理を開始します。
try内でデータベースの接続を開始するので、例外処理を定義しておきましょう。
データベースへ接続
$display = true;
//データベース接続
$dbh = new PDO(
'mysql:host=' . $host . '; dbname=' . $db_name . '; charset=utf8',
$user,
$pass,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
)
);
変数displayに、真理値のtrueを格納し、データベースへ接続します。

displayカラムにtrueを上書き
$sql = 'UPDATE com_table SET display=? WHERE id = ?';
$data[] = $display;
$data[] = $comment_id;
$stmt = $dbh->prepare($sql);
$stmt->execute($data);
UPDATE文を使って、displayカラムの値をtrueに上書きしています。

承認ボタンを押すと、そのコメントデータのdisplayカラムの値がtrueに上書きされます。
これが次のsave_comment.phpの鍵になります。
ここまでできたらdisplay.phpの作成は終了です。
次に、承認されたコメントを表示するために、save_comment.phpを修正します。
save_comment.phpの修正(1)
全体のコード
save_comment.phpを修正します。
まずは全体のコードを見てみましょう。
<?php
require 'db_info/db_info.php';
//データベース接続
try{
$dbh = new PDO(
'mysql:host=' . $host . '; dbname=' . $db_name . '; charset=utf8',
$user,
$pass,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
)
);
}catch(PDOException $e){
echo '<div class="server_error">現在サーバーエラーが発生しています。</div>';
}
//コメントが入力されたら
if($_SERVER['REQUEST_METHOD'] === 'POST'){
//メッセージの初期化
$error = '';
$success = '';
//入力値のチェック
if(empty($_POST['comment']) || empty($_POST['name']) || empty($_POST['email'])){
$error = '入力されていない項目があります。';
} elseif(strlen($_POST['comment']) > 1000){
$error = 'コメントは1000文字以内でご記入ください。';
} elseif(strlen($_POST['name']) > 15){
$error = 'お名前は15文字以内でご入力ください。';
} elseif(strlen($_POST['email']) > 100){
$error = 'メールアドレスは100文字以内でご入力ください。';
} else {
$comment = htmlspecialchars( $_POST['comment'] ,ENT_QUOTES, 'UTF-8');
$name = htmlspecialchars( $_POST['name'] ,ENT_QUOTES, 'UTF-8');
$email = htmlspecialchars( $_POST['email'] ,ENT_QUOTES, 'UTF-8');
try{
//SQL操作
$sql = 'INSERT INTO com_table(comment,name,email) VALUE (?,?,?)';
$data[] = $comment;
$data[] = $name;
$data[] = $email;
$stmt = $dbh->prepare($sql);
$stmt->execute($data);
$success = 'コメントを投稿しました。承認をお待ちください。';
}catch(PDOException $e){
echo '<div class="server_error">現在サーバーエラーが発生しています。</div>';
}
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>コメント入力ページ</title>
<meta name="viewport" content="width=1000">
<meta name="robots" content="noindex,nofollow">
<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="css/style.css">
</head>
<body>
<section class="wrap ww">
<img src="images/logo.jpg" class="ic">
<?php
if(isset($error)){
echo '<ul class="error"><li>' . $error . '</li></ul>';
}
if(isset($success)){
echo '<ul class="success"><li>' . $success . '</li></ul>';
}
?>
<form action="save_comment2.php" method="post" class="comment_form">
<label>コメント</label>
<textarea name="comment"></textarea>
<label>お名前</label>
<input type="text" name="name">
<label>メールアドレス</label>
<input type="email" name="email">
<input type="submit" name="submit" value="投稿">
</form>
<h2>コメント一覧</h2>
<ul class="comment_list">
<?php
try{
//SQL操作
$comlist_sql = 'SELECT * FROM com_table WHERE display=?';
$comlist_data[] = true;
$comlist_stmt = $dbh->prepare($comlist_sql);
$comlist_stmt->execute($comlist_data);
//承認(display = true)されたコメントのみ表示
while(true){
$row = $comlist_stmt->fetch(PDO::FETCH_ASSOC);
if($row == false){
break;
}
echo '<li>' . $row['comment'] . '<br><span class="name">by ' . $row['name'] . '</span></li>';
}
//接続解除
$dbh = null;
}catch(PDOException $e){
echo '<div class="server_error">現在コメントを取得できません。</div>';
}
?>
</ul>
</section>
</body>
</html>
変わった箇所はformタグ下部です。
<h2>コメント一覧</h2>
<ul class="comment_list">
<?php
try{
//SQL操作
$comlist_sql = 'SELECT * FROM com_table WHERE display=?';
$comlist_data[] = true;
$comlist_stmt = $dbh->prepare($comlist_sql);
$comlist_stmt->execute($comlist_data);
//承認(display = true)されたコメントのみ表示
while(true){
$row = $comlist_stmt->fetch(PDO::FETCH_ASSOC);
if($row == false){
break;
}
echo '<li>' . $row['comment'] . '<br><span class="name">by ' . $row['name'] . '</span></li>';
}
//接続解除
$dbh = null;
}catch(PDOException $e){
echo '<div class="server_error">現在コメントを取得できません。</div>';
}
?>
</ul>
では詳しく見ていきましょう。
接続解除のコード位置変更
注意して欲しいのは、データベース接続解除の一文の位置が変わったところです。
最初は変数successの直前にありましたが、今回、formタグ下部の新規追加コードの欄に移動しています。ここにだけ注意してください。
HTML部分
まずはHTML部分を解説します。
<h2>コメント一覧</h2>
<ul class="comment_list">
<?php
try{
//中略
}catch(PDOException $e){
echo '<div class="server_error">現在コメントを取得できません。</div>';
}
?>
</ul>
save_comment.phpでのコメント出力には、ulタグを使用します。出力したいのはコメントと投稿者名の2つだけなので、リスト形式でシンプルに作ってしまいましょう。
PHPはul内に記述していきます。
SQL文を記述するので、例外処理を定義しておきましょう。
承認されたコメントデータの取得
$comlist_sql = 'SELECT * FROM com_table WHERE display=?';
$comlist_data[] = true;
$comlist_stmt = $dbh->prepare($comlist_sql);
$comlist_stmt->execute($comlist_data);
displayカラムの値がtrueのデータを、全て取得します。

承認ボタンを押した場合だけ、displayカラムの値がtrueになります。ということは、displayカラムの値がtrueのコメントだけ表示すれば、承認されたコメントだけ表示できることになります。
承認コメントの出力
while(true){
$row = $comlist_stmt->fetch(PDO::FETCH_ASSOC);
if($row == false){
break;
}
echo '<li>' . $row['comment'] . '<br><span class="name">by ' . $row['name'] . '</span></li>';
}
dashboard.phpでデータを一覧表示した時のように、承認されたコメントをwhile文を使って出力します。
これでsave_comment.phpの修正は一旦終了です。
実際にコメントを承認してみましょう
display.phpとsave_comment.phpができたら、実際にコメントを承認しましょう。

無事に承認処理はできましたか?
では最後に『返信機能』を実装して、コメント管理画面を完成させましょう!
reply.phpの作成
コメント管理画面の最後の機能、返信機能を作りましょう!

<?php
session_start();
session_regenerate_id(true);
//エラー処理
if(!isset($_SESSION['id'])){
header('Location:login.php');
exit();
} else {
echo '<div class="top_bar"><p>こんにちは! ' . $_SESSION['email'] .'さん <a href="logout.php" class="logout_button">ログアウト</a></p></div>';
}
require '../db_info/db_info.php';
//idを取得
$comment_id = $_GET['id'];
if($_SERVER['REQUEST_METHOD'] === 'POST'){
//メッセージの初期化
$error = '';
$success = '';
if(empty($_POST['reply'])){
$error = '返信コメントが入力されていません。';
} elseif(strlen($_POST['reply']) > 1000){
$error = '返信コメントは1000文字以内でご記入ください。';
} elseif($error === '') {
$reply = htmlspecialchars( $_POST['reply'] ,ENT_QUOTES, 'UTF-8');
try{
//データベース接続
$dbh = new PDO(
'mysql:host=' . $host . '; dbname=' . $db_name . '; charset=utf8',
$user,
$pass,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
)
);
//SQL操作
$sql = 'UPDATE com_table SET reply=? WHERE id = ?';
$data[] = $reply;
$data[] = $comment_id;
$stmt = $dbh->prepare($sql);
$stmt->execute($data);
$success = 'コメントに返信しました。';
//接続解除
$dbh = null;
}catch(PDOException $e){
echo '<div class="server_error">現在サーバーエラーが発生しています。</div>';
}
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>コメント返信ページ</title>
<meta name="viewport" content="width=1000">
<meta name="robots" content="noindex,nofollow">
<link rel="stylesheet" type="text/css" href="../css/style.css">
</head>
<body>
<section class="wrap ww">
<?php
if(isset($error)){
echo '<ul class="error"><li>' . $error . '</li></ul>';
}
if(isset($success)){
echo '<ul class="success"><li>' . $success . '</li></ul>';
}
?>
<form action="reply.php?id=<?php echo $comment_id; ?>" method="post" class="comment_form">
<label>返信</label>
<textarea name="reply"></textarea>
<input type="submit" name="submit" value="返信">
</form>
<a href="dashboard.php" class="go_home">戻る</a>
</section>
</body>
</html>
reply.phpは下記のように配置してください。
hura_come
├── admin
│ ├── dashboard.php
│ ├── delete.php
│ ├── display.php
│ ├── login.php
│ ├── logout.php
│ ├── reply.php
│ └── update.php
├── css
│ └── style.css
├── db_info
│ └── db_info.php
└── save_comment.php
ではコードを細分化して詳しく説明していきます。
HTML部分
まずはHTMLから説明していきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>コメント返信ページ</title>
<meta name="viewport" content="width=1000">
<meta name="robots" content="noindex,nofollow">
<link rel="stylesheet" type="text/css" href="../css/style.css">
</head>
<body>
<section class="wrap ww">
<?php
if(isset($error)){
echo '<ul class="error"><li>' . $error . '</li></ul>';
}
if(isset($success)){
echo '<ul class="success"><li>' . $success . '</li></ul>';
}
?>
<form action="reply.php?id=<?php echo $comment_id; ?>" method="post" class="comment_form">
<label>返信</label>
<textarea name="reply"></textarea>
<input type="submit" name="submit" value="返信">
</form>
<a href="dashboard.php" class="go_home">戻る</a>
</section>
</body>
</html>
色々書いていますが、重要なのはform部分です。
<form action="reply.php?id=<?php echo $comment_id; ?>" method="post" class="comment_form">
<label>返信</label>
<textarea name="reply"></textarea>
<input type="submit" name="submit" value="返信">
</form>
同一ファイル内で処理を行うので、データの受け渡し先はreply.phpです。method属性にはpostを指定しましょう。
返信入力欄にはreplyと、name属性を与えます。
<?php
if(isset($error)){
echo '<ul class="error"><li>' . $error . '</li></ul>';
}
if(isset($success)){
echo '<ul class="success"><li>' . $success . '</li></ul>';
}
?>
今回はテキストエリアを利用するので、入力値のチェックを行わなくてはいけません。
コメント入力欄やログイン画面同様、エラーメッセージ・サクセスメッセージを表示できるように準備しておきましょう。
不正アクセス対策・db_info.phpの呼び出し・idの取得
次にPHPコードを見てみましょう。
session_start();
session_regenerate_id(true);
//エラー処理
if(!isset($_SESSION['id'])){
header('Location:login.php');
exit();
} else {
echo '<div class="top_bar"><p>こんにちは! ' . $_SESSION['email'] .'さん <a href="logout.php" class="logout_button">ログアウト</a></p></div>';
}
require '../db_info/db_info.php';
//idを取得
$comment_id = $_GET['id'];
ここは先ほど作ったdisplay.phpの部分と同じなので、説明は割愛させていただきます。
入力値のチェックとデータベース接続
if($_SERVER['REQUEST_METHOD'] === 'POST'){
//メッセージの初期化
$error = '';
$success = '';
if(empty($_POST['reply'])){
$error = '返信コメントが入力されていません。';
} elseif(strlen($_POST['reply']) > 1000){
$error = '返信コメントは1000文字以内でご記入ください。';
} elseif($error === '') {
$reply = htmlspecialchars( $_POST['reply'] ,ENT_QUOTES, 'UTF-8');
try{
//データベース接続
$dbh = new PDO(
'mysql:host=' . $host . '; dbname=' . $db_name . '; charset=utf8',
$user,
$pass,
array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
)
);
//中略
//接続解除
$dbh = null;
}catch(PDOException $e){
echo '<div class="server_error">現在サーバーエラーが発生しています。</div>';
}
}
}
ここでやっている事は、これまでのプログラムと類似するものばかりなので、簡単に説明させていただきます。
- このコードでしていること
- メッセージの初期化
- 入力値のチェック
- 入力値に誤りがなければ、返信内容をエスケープ処理し、変数replyに格納
- 例外処理を定義し、データベースへ接続
replyカラムに返信コメントを保存
$sql = 'UPDATE com_table SET reply=? WHERE id = ?';
$data[] = $reply;
$data[] = $comment_id;
$stmt = $dbh->prepare($sql);
$stmt->execute($data);
$success = 'コメントに返信しました。';
入力した内容を、replyカラムに上書きします。

これでreply.phpは完成です。
返信コメントもsave_comment.phpに表示させたいので、また少しだけ編集しましょう。
save_comment.phpの編集(2)
編集するのはwhile文だけです。
編集した部分だけ見てみましょう。
while(true){
$row = $comlist_stmt->fetch(PDO::FETCH_ASSOC);
if($row == false){
break;
}
echo '<li>' . $row['comment'] . '<br><span class="name">by ' . $row['name'] . '</span>';
//返信(replyに値)があれば表示
if(!empty($row['reply'])){
echo '<ul class="reply"><li>' . $row['reply'] . '</li></ul>';
}
echo '</li>';
}

実際にコメントに返信してみよう
reply.phpとsave_comment.phpができたら、実際にコメント返信してしましょう。

これまで、参照・編集・削除・承認・返信機能を作ってきましたが、無事全て作成できたでしょうか?

まとめ
今回制作したのは、display.phpとreply.phpです。
save_comment.phpも少し修正しました。
ここまで制作したら、下記のようなツリー構造になっていると思います。
hura_come
├── admin
│ ├── dashboard.php
│ ├── delete.php
│ ├── display.php
│ ├── login.php
│ ├── logout.php
│ ├── reply.php
│ └── update.php
├── css
│ └── style.css
├── db_info
│ └── db_info.php
└── save_comment.php
