3
1

More than 3 years have passed since last update.

よくある掲示板を1から積み上げて作る〜導入〜

Last updated at Posted at 2020-12-05

本記事の概要

掲示板の作成を通して
MVC について学びたいという初心者が
github.com/sait0928/bbs
↑このリポジトリについて
初期のコミットから段階を追って振り返りつつ、
記事を作成することで復習し
理解を深めたい、
ということで作成した記事でございます。
複数に分けて投稿していく予定です。

筆者はどのくらいのレベルなのかという話

  • プログラマのアルバイトを半年ほど経験
  • うち研修3ヶ月、実務は3ヶ月ほど
  • 退社してから1年ほどブランクあり
  • PHP, DB, 仮想マシンは使ったことがある
  • HTML は最低限書ける
  • レベルはおそらく底辺

環境構築で参考にした記事・サイト

仮想マシンの準備

仮想マシン上のファイルをホストで扱いたい

やることリストを書いていく

最初はとにかくシンプルなものを作る
(いきなり色々やろうとするとテンションが上がらない)

## 掲示板を作る
- データベース
- フォーム部分
- 表示部分

機能や部品、必要なテーブルについても考える

## ユーザーが使える機能
- フォームから送信する
- 投稿を表示する
## 必要な部品
- 投稿用テキストボックス
- 投稿用ボタン
- 投稿表示リスト
## データベース
- 投稿id
- 投稿内容

実際に作っていく

まずはHTMLだけ

本来PDOを使って
テーブルから SELECT してくる部分は
適当に固定値を埋めて
形だけ作ってしまえ、ということで

index.php
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>掲示板</title>
    </head>
    <body>
        <h1>掲示板</h1>
        <div id="form">
            <form action="" method="POST">
                <textarea name="text" id="" cols="50" rows="5"></textarea>
                <input type="submit" value="投稿">
            </form>
        </div>
        <div id="posts">
            <table>
                <tr>
                    <th>投稿ID</th>
                    <th>投稿内容</th>
                </tr>
                <?php for($i = 0; $i < 10; $i++) : ?>
                <tr>
                    <td>id</td>
                    <td>text</td>
                </tr>
                <?php endfor; ?>
            </table>
        </div>
    </body>
</html>

テーブルを作る

posts.sql
create table posts(
    id int auto_increment,
    post varchar(255) not null,
    primary key (id)
);

PDOを書いていく

PDOがなんなのか分からない、という方は
こちらの記事を見ると良いです。

- 【PHP超入門】クラス~例外処理~PDOの基礎

まずはテーブルから記事を取得してくる処理

index.php
<?php

$dsn = 'mysql:dbname=bbs;host=localhost';
$user = 'root';
$pass = '';

try {
    $dbh = new PDO($dsn, $user, $pass);
    $stmt = $dbh->query('SELECT * FROM posts ORDER BY id DESC');
    $posts = $stmt->fetchAll();
} catch(PDOException $e) {
    $error = $e->getMessage();
    echo $error;
}

?>
<!DOCTYPE html>
<!-- 以下html -->

ここで取得した posts を
html で表示できるように書いていきます。

index.php
<table>
    <tr>
        <th>投稿ID</th>
        <th>投稿内容</th>
    </tr>
    <?php foreach($posts as $post) : ?>
    <tr>
        <td><?php echo $post['id']; ?></td>
        <td><?php echo nl2br(htmlspecialchars($post['post'])); ?></td>
    </tr>
    <?php endforeach; ?>
</table>

値のエスケープを忘れないようにしましょう。
また、htmlspecialchars()
必ず html 出力時に行うようにしましょう。

【脆弱性対策におけるhtmlspecialchars()の使用箇所について】

ちなみに、
PDO 使用の際に
could not find driver
というエラーが出たので、
こちらの記事を参考に解決いたしました。

【PDOで could not find driver が出たとき】

続いてフォームで送信したテキストを
テーブルに書き込む処理です。
先ほど SELECT の際に生成した PDO インスタンスを
使いまわします。

index.php
try {
    $dbh = new PDO($dsn, $user, $pass);

    // 記事書き込み部分
    if($_SERVER['REQUEST_METHOD'] === 'POST') {
        $text = $_POST['text'];
        $stmt = $dbh->prepare('INSERT INTO posts (post) VALUES (:post)');
        $stmt->bindParam(':post', $text, PDO::PARAM_STR);
        $stmt->execute();
    }
    // 記事書き込み終わり

    $stmt = $dbh->query('SELECT * FROM posts ORDER BY id DESC');
    $posts = $stmt->fetchAll();
} catch(PDOException $e) {
    $error = $e->getMessage();
    echo $error;
}

途中で prepare() を使って
:post というプレースホルダを作っておき
後から値をバインドしていますが、
これはSQLインジェクションという脆弱性への対策です。

SQLインジェクションとクエリの書き方について考える

これでこじんまりとした掲示板は完成しました。

あとがき 〜今後の作業の流れ〜

初心者のうちに書いた初心者目線の記事はある程度需要がありそう
ということで Qiita デビュー作でした。

ここからは、
良くないと思われる部分を修正したり、
機能を追加したりしつつ、
関数分割できるものは分割したり、
ある程度まとまってきたら
Model, View, Controller に分けてみたり、
そのようにして
なんだかフレームワークで見たことのある構成に
していくという流れになります。

数ヶ月前を振り返りつつの解説になるため
何を悩んでいたか忘れている部分もありますが、
色々な方にツッコんでいただきつつ
初心者向けの記事に仕上げていきたいと思っております。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1