第10回 DBとPOSTとGETを使って簡単な掲示板(BBS)を作ろう

第八回、九回とDBに関する操作を学習してきました。
今回は前回の宿題の解説と、その応用編としてPHPで掲示板(BBS)を作ってみましょう。

SQLの基本操作

前回の設問の解答と解説

前回解いてもらった設問の解答と解説を行います。
第九回講義設問内容
データ表見本完成形

解答

/*データの呼び出し*/
//個人データとテスト3科目の個人合計ですが
$stmt = $pdo->query('SELECT *, (score_1 + score_2 + score_3) as score_all FROM user');
$list = $stmt->fetchAll();

//各教科の合計点数
$stmt = $pdo->query('SELECT SUM(score_1) as score_1_all, SUM(score_2) as score_2_all, SUM(score_3) as score_3_all, SUM(score_1+score_2+score_3) as score_all FROM user');
$row = $stmt->fetchObject();
/*呼び出したデータの表示*/
<tbody>
	<?php foreach($list as $key => $val):?>
	<tr>
		<td><?php echo $val['user_id']; ?></td>
		<td><?php echo $val['user_name']; ?></td>
		<td><?php echo $val['class']; ?></td>
		<td><?php echo $val['score_1']; ?></td>
		<td><?php echo $val['score_2']; ?></td>
		<td><?php echo $val['score_3']; ?></td>
		<td><?php echo $val['score_all']; ?></td>
	</tr>
	<?php endforeach; ?>
	<tr>
		<th>合計</th>
		<td class="text-center">------</td>
		<td class="text-center">------</td>
		<td><?php echo $row->score_1_all; ?></td>
		<td><?php echo $row->score_2_all; ?></td>
		<td><?php echo $row->score_3_all; ?></td>
		<td><?php echo $row->score_all; ?></td>
	</tr>
</tbody>

解説

テスト3科目の個人合計ですが

(score_1 + score_2 + score_3) as score_all

とし、各科目の合計したものをデータで呼び出します。
算数と同じで、『+』を使う事で、足し算を行っています。

一方、各教科の合計点数のほうは、

SUM(score_1) as score_1_all, SUM(score_2) as score_2_all, SUM(score_3) as score_3_all, SUM(score_1+score_2+score_3) as score_all

として合計したものを呼び出すようにしています。
こういう使い方ができると理解してもらえば十分です。

あとは表示の方ですが、指定した名称を記述して呼び出すだけなのですが、実際、難しいです。

<?php echo $row->score_1_all; ?>

上記の呼び出し方は講義内で学習したものではないので、自発的に検索しないことには解答にたどり着けないかもしれません。
しかし、理解してみると書き方に法則性があるので、次からは簡単に解けるのではないかと思います。

以上、解答と解説になります。

掲示板(BBS)とは?

電子掲示板(でんしけいじばん、BBS、英語: Bulletin Board System)とは、コンピュータネットワークを使用した環境で、記事を書き込んだり、閲覧したり、コメント(レス)を付けられるようにした仕組みのことである。単に「掲示板」と呼んだり、英語表記の略語で “BBS” と呼んだりする。

わかりやすいもので言うと、5ch(旧2ch)などの文章を打ち込んだ順に並んで表示されるサイトがあります。
本講義ではそんなBBSの簡易版を作成したいと思います。

BBSの完成例

では先にBBSの完成図を見てみましょう。
BBS完成例

ページを開くと、上の段に投稿された内容が並び、下の段に投稿用フォームがあります。
名前は省略可になっており、省略すると名無しとして投稿されます。
投稿日時の隣にある『削除』のリンクは、クリックするとその該当する投稿が1件削除されます。

こんな簡素的なBBSをこれから作っていきます。

BBSの作成準備

DB作成SQL

では、掲示板のもとになるDBを作成しましょう。
以下のSQLを利用して、DB「db_test_003」を作成してください。

CREATE DATABASE IF NOT EXISTS `db_test_003` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
USE `db_test_003`;

CREATE TABLE `bbs` (
  `id` int(11) NOT NULL,
  `user_name` varchar(255) DEFAULT NULL,
  `text` text NOT NULL,
  `cdate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ALTER TABLE `bbs`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `bbs`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;

DBの構成

作られたDBの構成を確認してみましょう。
id:BBSの作成番号(AUTO_INCREMENT)
user_name:投稿者名
text:コメント内容
cdate:書き込み日時(CURRENT_TIMESTAMP)

今回は簡易的なBBSを作成するという事なので、入力項目を減らし、返信機能をいれていません。
最低限必要なものとして、上記のものが残ることになります。

BBSの作成と表示

DBの準備ができたので、PHPファイルを作成していきます。

設問ファイル

続いて、C:\xampp\htdocs内にdb_test_003.phpファイルを作成し、以下をコピペします。

<?php

require_once('db_connect.php');
try {
    // データベースに接続
	$db_name = 'db_test_003';
    $pdo = db_connect($db_name);

	$url = "http://".$_SERVER["HTTP_HOST"].$_SERVER["SCRIPT_NAME"];

if(isset($_POST['text'])){
	if(empty($_POST['text'])){
		$class = 'is-invalid';
	}else{
		$class = '';
		$text = $_POST['text'];
		$user_name = ($_POST['user_name'])? $_POST['user_name'] : '名無し';

		$sql = "INSERT INTO bbs (user_name, text) VALUES (:user_name, :text)";
		$stmt = $pdo->prepare($sql);
		$stmt->bindParam(':user_name', $user_name, PDO::PARAM_STR);
		$stmt->bindParam(':text', $text, PDO::PARAM_STR);
		//$params = array(':user_name' => $user_name, ':text' => $text);
		$stmt->execute();
		header('Location: '.$url);
		exit;
	}
}

if(isset($_GET['id'])){
	$id = $_GET['id'];
	$sql = 'DELETE FROM bbs where id = :id';
	$stmt = $pdo -> prepare($sql);
	$stmt -> bindParam(':id', $id, PDO::PARAM_INT);
	$stmt -> execute();

	header('Location: '.$url);
	exit;
}
    //例外処理を投げるようにする(throw)
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

	$stmt = $pdo->query('SELECT * FROM bbs ORDER BY id DESC');
	$list = $stmt->fetchAll();
	
    //データベース接続切断
    $pdo = null;

} catch (PDOException $e) {
    // エラーが発生した場合は「500 Internal Server Error」でテキストとして表示して終了する
    header('Content-Type: text/plain; charset=UTF-8', true, 500);
    exit($e->getMessage()); 
}

?>

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>db_test_003</title>
		<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<style>
.wrp-bbs{margin-bottom: 40px;}
.item-bbs{background-color:#eee; padding:15px; margin-bottom: 10px;}
.item-name{color: green; font-weight: bold; margin: 0 20px;}
.item-bbs p{margin: 15px 0 0;}
.wrp-form{max-width: 600px;}
</style>
    </head>
    <body>
		<div class="container wrp-bbs">
			<p class="lead my-4">BBS</p>
			<?php foreach($list as $key => $val):?>
				<div class="item-bbs">
					<div class="item-head">
						<span class="item-id"><?php echo $val['id']; ?></span>
						<span class="item-name"><?php echo $val['user_name']; ?></span>
						<span class="item-date"><?php echo $val['cdate']; ?></span>
						<a class="item-delete" href="?id=<?php echo $val['id']; ?>">削除</a>
					</div>
					<p><?php echo nl2br($val['text']); ?></p>
				</div>
			<?php endforeach; ?>
		</div>
			
		<div class="container wrp-form">
			<form id="form" method="POST" action="#form">
				<legend>レスを投稿する</legend>
				<div class="form-group">
					<input type="text" name="user_name" class="form-control" placeholder="名前(省略可)">
				</div>

				<div class="form-group">
					<textarea class="form-control <?php echo $class; ?>" name="text" placeholder="コメント内容" rows="5"></textarea>
					<div class="invalid-feedback">コメントは必ず入力してください。</div>
				</div>
				<button type="submit" class="btn btn-primary">書き込む</button>
			</form>
		</div>
    </body>
</html>

POSTとGET

設問の解説を前に、POSTGETを解説します。

BBSを作るには、フォームから情報を飛ばして受け取る必要があり、PHPではその受け取り方としてPOSTとGETがあります。
POST:データがURLで引き渡されない
GET:データがURLで引き渡される
簡単に言うと、目に見えるか見えないかの違いと言ったところです。

要所要所で使い分けされ、POSTはメールフォームなどで利用され、GETはメール認証時のURLによく使われています。

設問の解説

コードを上から順になぞりながら説明していきます。
処理としては以下の流れになります。
細かい説明になるので、講義内でお話しいたします。

  1. DBの接続
  2. POSTの判別分岐
  3. コメントが空だった場合のバリデーション
  4. INSERT処理
  5. リダイレクト処理
  6. GETの判別分岐
  7. 投稿の削除
  8. データの取得
  9. 追加CSS
  10. BBS表示
  11. 投稿フォーム

講義に出られなかった方は、以下の解説がとても分かりやすいので参考にしてください。
PHPでフォームからデータを受け取る方法(GETとPOST) | TechAcademyマガジン

まとめ

今回の講義をまとめると、以下のようになります。

  • MySQL関数には、数値を扱って合計や平均を取得するものがある
  • BBSにはプログラミングの基礎的な知識、ノウハウが詰まっている
  • データの扱いにはPOSTとGETがある

今回の講義では、DBの扱いである最終章、BBSの作成を行いました。
BBSが作成できるという事は、DB、PHP、HTMLの理解が必要になります。

この理解が深まると、一気にプログラミングというものが身近になってくるので、理解できるまで触れてたり、機能追加を行ってみましょう。

次回講義までの自主学習

基礎としてHTMLとCSSは必須となりますので、できるかぎり触れましょう。
学習サイトをピックアップしたので、以下のリンクから自分に合ったものを使って自主学習しましょう。

NEW!!

PHPで作る簡易掲示板 (全9回) – プログラミングならドットインストール
SQL | プログラミングの入門なら基礎から学べるProgate[プロゲート]
MySQL入門 (全36回) – プログラミングならドットインストール

基礎知識

HTML & CSS | プログラミングの入門なら基礎から学べるProgate[プロゲート]
HTML/CSS入門編のレッスン一覧 | プログラミング学習サービス【paizaラーニング】
HTML入門 (全15回) – プログラミングならドットインストール
CSS入門 (全17回) – プログラミングならドットインストール
実践!ウェブサイトを作ろう (全16回) – プログラミングならドットインストール

STEP UP!!

はじめてのJavaScript (全11回) – プログラミングならドットインストール
JavaScript入門編のレッスン一覧 | プログラミング学習サービス【paizaラーニング】
JavaScript | プログラミングの入門なら基礎から学べるProgate[プロゲート]
Bootstrap 4入門 (全22回) – プログラミングならドットインストール

さらにSTEP UP!!

PHP入門編のレッスン一覧 | プログラミング学習サービス【paizaラーニング】
PHP | プログラミングの入門なら基礎から学べるProgate[プロゲート]
PHP入門 (全30回) – プログラミングならドットインストール

理想はすべてのレッスンをやることです。
今は目で見て手で触れる時間を増やすときなので、時間が許す限りやってみましょう。