LAMP環境で掲示板を作る

はじめに

先に述べておきますが今回は長い記事となりますのでご了承ください。

  • PHP
  • MySQL
  • Docker

上の3つに関してのある程度の知識は有るものとして解説していきます。と言っても簡単なので初見さんでもコピペで構築が出来るようになっています。

フォルダ構成

$ tree .
.
|-- docker
|   `-- db
|       |-- data
|       |-- my.cnf
|       `-- sql
|           |-- 001-create-tables.sql
|           `-- init-database.sh
|-- docker-compose.yml
|-- php
|   |-- article.php
|   |-- css
|   |   `-- style.css
|   |-- Dockerfile
|   `-- index.php
`-- README.md
  • db系
    • dataディレクトリ
      • 設定ファイルが勝手に入るディレクトリ
    • my.cnf
      • 文字コードなどdbの初期設定
    • 001-create-tables.sql
      • データベース/テーブル作成クエリ
    • init-database.sh
      • 001-create-tables.sqlを実行するスクリプト
  • docker-compose.yml
    • dockerのプレイブック
  • php系
    • article.php
      • 記事用ページ
    • style.css
      • スタイルシート
    • Dockerfile
      • phpインストールのプレイブック
    • index.php
      • トップ用ページ

この辺が編集していくファイルになります。

プレイブック

$ vi docker-compose.yml
version: '2'
services:
  # php:apache
  app:
    build:
      context: ./php
      dockerfile: Dockerfile
    container_name: php_apa
    volumes:
      - ./php:/var/www/html:z
    ports:
      - 80:80
    depends_on:
      - db
    links:
      - db:mysql

  # MySQL
  db:
    image: mysql:5.7
    container_name: mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: test_db
      MYSQL_USER: root
      MYSQL_PASSWORD: password
      TZ: 'Asiz/Tokyo'
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
    - ./docker/db/data:/var/lib/mysql:z
    - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf:z
    - ./docker/db/sql:/docker-entrypoint-initdb.d:z
    ports:
    - 3306:3306

ApacheとMySQLでコンテナを二つ用意します。今回は構築が目的で運用は考慮していないのでアカパスは適当なものにしています。

$ vi php/Dockerfile
FROM php:7.2-apache

RUN docker-php-ext-install pdo_mysql

このままPHPファイルを解説するよりもDBを先に見ておいた方が分かりやすいと思うので、MySQLの初期クエリから見ていきたいと思います。

MySQL

$vi docker/db/sql/001-create-tables.sql
---- Create TitleTable ----
CREATE DATABASE IF NOT EXISTS keijiban_db;
USE keijiban_db;
DROP TABLE IF EXISTS title_table;
create table title_table
(
 id             INT(4) AUTO_INCREMENT NOT NULL PRIMARY KEY,
 title_id       VARCHAR(15),
 title          VARCHAR(200),
 last_com       DATETIME,
 total_com      INT(4)
) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

---- Create CommentTable1 ----
CREATE DATABASE IF NOT EXISTS keijiban_db;
DROP TABLE IF EXISTS 2019_0923_1357;
create table 2019_0923_1357
(
 id INT(4) AUTO_INCREMENT NOT NULL PRIMARY KEY,
 user           VARCHAR(100),
 comment        TEXT,
 date_com       DATETIME
) DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

---- insert ----
START TRANSACTION;
insert into title_table (title_id, title, last_com, total_com) value ('2019_0923_1357', 'テスト用ダミースレ', '2019-09-23 13:57', 1);
insert into 2019_0923_1357 (user, comment, date_com) value ('通行人A', 'おわた!', '2019-09-23 13:57');
COMMIT;
$ vi docker/db/sql/init-database.sh
#!/usr/bin/env bash
mysql -u root -ppassword < "/docker-entrypoint-initdb.d/001-create-tables.sql"

このスクリプトはMySQLコンテナで実行します。

title_tableテーブル

タイトル名とタイトルIDを管理するテーブルになります。

概要カラム名
IDid1INT(4)
スレタイIDtitle_idYYYY_MMDD_hhmmssVARCHAR(15)
スレタイtitleテスト用ダミースレVARCHAR(200)
最終書込日時last_comYYYY-MM-DD hh:mm:ssDATETIME
書込総数 total_com999INT(4)

YYYY_MMDD_hhmmテーブル

コメントなどを管理するテーブルです。

概要カラム名
IDid1INT(4)
書込者user通行人AVARCHAR(100)
書込commentおわた!TEXT
書込日時date_comYYYY-MM-DD hh:mm:ssDATETIME

DBはこんな感じです。意外とシンプルです。

PHP

先に完成予想図を見ておきます。

まずは今回のPHPの動作を確認します。

  • POST要求チェック
    • フォームにデータが入力されて送信されているかどうか
  • DB挿入/抽出
    • POSTデータが正しく入力されていればDB挿入
    • DBから現状のデータを抽出
  • レンダリング
    • 抽出したデータを元にレンダリングHTMLを作成

トップページ

トップページから作成しましょう。

$ vi php/index.php
<?php
        date_default_timezone_set('Asia/Tokyo');

        /**********************************/
        /*            DB諸情報            */
        /*コンテナから見えるホスト名を設定*/
        /*   ホスト名にはmysqlコンテナid  */
        /*         GlobalIPを記入         */
        /* $_SERVER['QUERY_STRING']はparm */
        /**********************************/
        define('DB_DATABASE', 'keijiban_db');
        define('DB_USERNAME', 'root');
        define('DB_PASSWORD', 'password');
        define('PDO_DSN', 'mysql:host=【MySQLコンテナID】;dbname=' . DB_DATABASE);
        $gip = '【WEBサーバIP】';

        /******************************************/
        /*              スレ作成エリア            */
        /*                    (1)                 */
        /*Insert title_table & Create CommentTable*/
        /******************************************/
        if ( !empty($_POST['make_sled_input_sleti']) ) {
                $input_sleti = $_POST['make_sled_input_sleti'];
                $sle_timestamp = date("Y_md_Hi");
                $dummy_first_comment_timestamp = date("Y-m-d H:i:s");

                if ( strcmp($input_sleti, "スレッド名") == 0 ) {
                        echo "あのねあのねスレッド名が空なの";
                } else if ( strcmp($input_sleti, "") == 0 ) {
                        //リロード時の初期値NULLなので何もしない
                } else {
                        $sql3 = "CREATE TABLE $sle_timestamp (
                                        id              INT(4) AUTO_INCREMENT NOT NULL PRIMARY KEY,
                                        user            VARCHAR(100),
                                        comment         TEXT,
                                        date_com        DATETIME
                                ) DEFAULT CHARSET=utf8 COLLATE=utf8_bin";
                        $sql4 = "INSERT INTO title_table (title_id, title, last_com, total_com) value ('{$sle_timestamp}', '{$input_sleti}', '{$dummy_first_comment_timestamp}', 1)";

                        try {
                                $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
                                $arr = $db->query($sql3, PDO::FETCH_ASSOC);
                                $arr2 = $db->query($sql4, PDO::FETCH_ASSOC);
                                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                        } catch (PDOException $e) {
                                echo $e->getMessage();
                                exit;
                        }
                }
        $redirect_url = "{$_SERVER['PHP_SELF']}".'?'."{$title_id}";
        header("Location: $redirect_url");
        exit;
        }
?>

<html>
<head>
        <meta charset="utf-8">
        <?php
                echo "<title>トップページ</title>"
        ?>
        <link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1 style="text-align:center;">掲示板 on Docker</h1>
<?php
        /**********************************/
        /*         スレタイエリア          */
        /*          レンダリング           */
        /**********************************/
        echo "<div style=\"border: 1px solid#3399FF;\" class=\"sleti_area\">";

        /**************************************/
        /*                 (1)                */
        /*  Title Table からスレタイ総数抽出  */
        /*最終行のidを取得するためにはこれしか*/
        /*        なかったんです......        */
        /*              $title_num            */
        /**************************************/
        $sql = 'SELECT id FROM title_table ORDER BY id desc limit 1';

        try {
                $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
                $arr = $db->query($sql, PDO::FETCH_ASSOC);
                foreach($arr as $que_res) {
                        if ($que_res === reset($arr)) {
                                echo "これは何の条件分岐";
                        }
                        $title_num = $que_res['id'];
                        if ($que_res === end($arr)) {
                                echo "これは何の条件分岐";
                        }
                }
                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
                echo $e->getMessage();
                exit;
        }
        /**************************************/
        /*                 (2)                */
        /*  title_tableから更新日時など抽出   */
        /**************************************/
        $sql = 'SELECT * FROM title_table ORDER BY id DESC';
        try {
                $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
                $arr = $db->query($sql, PDO::FETCH_ASSOC);
                foreach($arr as $que_res) {
                        if ($que_res === reset($arr)) {
                                echo "";
                        }
                        echo "<p class=\"slti\"><a href=\"http://", $gip, "/article.php", "?", $que_res['title_id'], "\" target=\"_blank\">【", $que_res['last_com'], "】 ", $que_res['title'], "</a></p>";
                        if ($que_res === end($arr)) {
                                echo "";
                        }
                }

                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
                echo $e->getMessage();
                exit;
        }
        echo "</div>";

        /**********************************/
        /*         コメントエリア         */
        /*               (1)              */
        /* INSERT処理後にレンダリングする */
        /**********************************/
        echo "<div style=\"border: 1px solid #3399FF;\" class=\"comment_area\">";
        echo "<p style=\"margin-top:0; margin-bottom:20px; font-size:15px; text-align:left;\">直近のコメへ移動</p>";

        echo "<div class=\"input_com_block\">";
        echo "<form method=\"post\" action=\"\" enctype=\"multipart/form-data\">";
        echo "<input type=\"text\" name=\"input_name\" value=\"名前\" class=\"input_name\" onfocus=\"if(this.value==this.defaultValue){this.value='';this.style.color='black';}\" onblur=\"if(this.value==''){this.value=this.defaultValue;this.style.color='#999999'}\"/><br>";
        echo "<input type=\"file\" name=\"input_fname\"><br>";
        echo "<textarea name=\"input_comment\" class=\"input_comment\" onfocus=\"if(this.value==this.defaultValue){this.value='';this.style.color='black';}\" onblur=\"if(this.value==''){this.value=this.defaultValue;this.style.color='#999999'}\" >コメント</textarea><br>";
        echo "<input type=\"submit\" name=\"send\" value=\"書き込む\" class=\"input_com_button\" />";
        echo "</form>";
        echo "</div>";

        echo "</div>";

        /**********************************/
        /*         スレ作成エリア         */
        /*                (2)             */
        /*          レンダリング          */
        /**********************************/
        echo "<div style=\"border: 1px solid #3399FF;\" class=\"make_sled_area\">";
        echo "<div class=\"explain_block\">";
        echo "<h2 style=\"margin:0;\">ルール</h2>";
        echo "<ul class=\"explain_list\"><li>書き込めるのは現状テキストのみ</li><li>荒らしたら負け</li></ul>";
        echo "</div>";

        echo "<div class=\"make_sled_block\">";
        echo "<form method=\"post\" action=\"\">";
        echo "<input type=\"text\" name=\"make_sled_input_sleti\" value=\"スレッド名\" class=\"make_sled_input_sleti\" onfocus=\"if(this.value==this.defaultValue){this.value='';this.style.color='black';}\" onblur=\"if(this.value==''){this.value=this.defaultValue;this.style.color='#999999'}\"/><br>";
        echo "<input type=\"submit\" name=\"send_sle\" value=\"スレッドを立てる\" class=\"button_sle\" />";
        echo "</form>";
        echo "</div>";

        echo "</div>";

        echo "<div class=\"backtop\">";
        echo "<a href=\"#\">ページ上部へ移動</a>";
        echo "</div>";
?>
</body>
</html>
  • 23~54行:スレ作成用のPOSTデータがあればテーブル作成とtitle_tableへのINSERT処理を実行する
  • 52~53行:POSTデータをクリアする
  • 57行以降:レンダリング処理
  • index.phpはコメント入力処理はありません

記事ページ

次は記事ページを作成します。基本的にはトップページと中身は同じです。

$ vi php/article.php
<?php
        date_default_timezone_set('Asia/Tokyo');
        /**********************************/
        /*            DB諸情報            */
        /*コンテナから見えるホスト名を設定*/
        /*   ホスト名にはmysqlコンテナid  */
        /*         GlobalIPを記入         */
        /* $_SERVER['QUERY_STRING']はparm */
        /**********************************/
        define('DB_DATABASE', 'keijiban_db');
        define('DB_USERNAME', 'root');
        define('DB_PASSWORD', 'password');
        define('PDO_DSN', 'mysql:host=【MySQLコンテナID】;dbname=' . DB_DATABASE);
        $gip = '【WEBサーバIP】';
        $title_id = $_SERVER['QUERY_STRING'];

        $first_sql = "SELECT title FROM title_table WHERE title_id='{$title_id}'";
        try {
                $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
                $title_name_arr = $db->query($first_sql, PDO::FETCH_ASSOC);
                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                foreach($title_name_arr as $que_res) {
                        $title_name = $que_res['title'];
                }
        } catch (PDOException $e) {
                echo $e->getMessage();
                exit;
        }

        /*********************************************************/
        /*                    コメントエリア                      */
        /*                          (1)                          */
        /*            レンダリング前にINSERT処理を実施             */
        /* POSTが来たらPOSTクリアするためにheader()でGETリクエスト  */
        /*               header()はレンダリングの前               */
        /*********************************************************/
        if ( !empty($_POST['input_comment']) ) {
                $input_name = $_POST['input_name'];
                $input_comment = $_POST['input_comment'];
                $input_comment_time = date("Y-m-d H:i:s");

                //リロードの度にINSERTしないようにクエリ変数初期化
                //commentブロックのレンダリング前だから$input_commentがNULLの場合も弾く必要がある
                //リロード時のPOSTクリア
                if ( strcmp($input_comment, "コメント") == 0 ) {
                        echo "あのねあのねコメントが空なの";
                } else if ( strcmp($input_comment, "") == 0 ) {
                //リロード時の初期値NULLなので何もしない
                } else {
                        $sql = "INSERT INTO {$title_id} (user, comment, date_com) value ('{$input_name}', '{$input_comment}', '{$input_comment_time}')";
                        $sql2 = "UPDATE title_table SET last_com='{$input_comment_time}' WHERE title_id='{$title_id}'";
                        try {
                                $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
                                $arr = $db->query($sql, PDO::FETCH_ASSOC);
                                $arr2 = $db->query($sql2, PDO::FETCH_ASSOC);
                                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                        } catch (PDOException $e) {
                                echo $e->getMessage();
                                exit;
                        }
                }
                $redirect_url = "{$_SERVER['PHP_SELF']}".'?'."{$title_id}";
                header("Location: $redirect_url");
                exit;
        }

        /******************************************/
        /*              スレ作成エリア            */
        /*                    (1)                 */
        /*Insert title_table & Create CommentTable*/
        /******************************************/
        if ( !empty($_POST['make_sled_input_sleti']) ) {
                $input_sleti = $_POST['make_sled_input_sleti'];
                $sle_timestamp = date("Y_md_Hi");
                $dummy_first_comment_timestamp = date("Y-m-d H:i:s");

                if ( strcmp($input_sleti, "スレッド名") == 0 ) {
                        echo "あのねあのねスレッド名が空なの";
                } else if ( strcmp($input_sleti, "") == 0 ) {
                        //リロード時の初期値NULLなので何もしない
                } else {
                        $sql3 = "CREATE TABLE $sle_timestamp (
                                        id              INT(4) AUTO_INCREMENT NOT NULL PRIMARY KEY,
                                        user            VARCHAR(100),
                                        comment         TEXT,
                                        date_com        DATETIME
                                ) DEFAULT CHARSET=utf8 COLLATE=utf8_bin";
                        $sql4 = "INSERT INTO title_table (title_id, title, last_com, total_com) value ('{$sle_timestamp}', '{$input_sleti}', '{$dummy_first_comment_timestamp}', 1)";

                        try {
                                $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
                                $arr = $db->query($sql3, PDO::FETCH_ASSOC);
                                $arr2 = $db->query($sql4, PDO::FETCH_ASSOC);
                                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
                        } catch (PDOException $e) {
                                echo $e->getMessage();
                                exit;
                        }
                }
        $redirect_url = "{$_SERVER['PHP_SELF']}".'?'."{$title_id}";
        header("Location: $redirect_url");
        exit;
        }
?>

<html>
<head>
        <meta charset="utf-8">
        <?php
                echo "<title>{$title_name}</title>";
        ?>
        <link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1 style="text-align:center;">掲示板 on Docker</h1>
<?php
        /**********************************/
        /*          スレタイエリア         */
        /*           レンダリング          */
        /**********************************/
        echo "<div style=\"border: 1px solid#3399FF;\" class=\"sleti_area\">";

        /**************************************/
        /*                 (1)                */
        /*  Title Table からスレタイ総数抽出  */
        /*最終行のidを取得するためにはこれしか*/
        /*        なかったんです......        */
        /*              $title_num            */
        /**************************************/
        $sql = 'SELECT id FROM title_table ORDER BY id desc limit 1';

        try {
                $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
                $arr = $db->query($sql, PDO::FETCH_ASSOC);
                foreach($arr as $que_res) {
                        if ($que_res === reset($arr)) {
                                echo "これは何の条件分岐";
                        }
                        $title_num = $que_res['id'];
                        if ($que_res === end($arr)) {
                                echo "これは何の条件分岐";
                        }
                }
                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
                echo $e->getMessage();
                exit;
        }
        /**************************************/
        /*                 (2)                */
        /*  title_tableから更新日時など抽出   */
        /**************************************/
        $sql = 'SELECT * FROM title_table ORDER BY id DESC';
        try {
                $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
                $arr = $db->query($sql, PDO::FETCH_ASSOC);
                foreach($arr as $que_res) {
                        if ($que_res === reset($arr)) {
                                echo "これは何の条件分岐";
                        }
                        echo "<p class=\"slti\"><a href=\"http://", $gip, "/article.php", "?", $que_res['title_id'], "\" target=\"_blank\">【", $que_res['last_com'], "】 ", $que_res['title'], "</a></p>";
                        if ($que_res === end($arr)) {
                                echo "これは何の条件分岐";
                        }
                }

                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
                echo $e->getMessage();
                exit;
        }
        echo "</div>";

        /**********************************/
        /*         コメントエリア         */
        /*               (2)              */
        /* INSERT処理後にレンダリングする */
        /**********************************/
        echo "<div style=\"border: 1px solid #3399FF;\" class=\"comment_area\">";
        echo "<p style=\"margin-top:0; margin-bottom:20px; font-size:15px;\"><a href=\"#lastcom\">直近のコメへ移動</a></p>";

        $sql2 = 'SELECT * from '.$title_id;
        try {
                $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
                $arr = $db->query($sql2, PDO::FETCH_ASSOC);
                foreach($arr as $que_res) {
                        if ($que_res === reset($arr)) {
                                echo "これは何の条件分岐";
                        }
                        echo "<p class=\"comment_header\">", $que_res['id'], ":", $que_res['user'], ":", $que_res['date_com'], "</p>";
                        echo "<p class=\"comment\">", $que_res['comment'];
                        if ($que_res === end($arr)) {
                                echo "これは何の条件分岐";
                        }
                }

                $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
                echo $e->getMessage();
                exit;
        }

        echo "<div class=\"input_com_block\">";
        echo "<form method=\"post\" action=\"\" enctype=\"multipart/form-data\">";
        echo "<input type=\"text\" name=\"input_name\" value=\"名前\" class=\"input_name\" onfocus=\"if(this.value==this.defaultValue){this.value='';this.style.color='black';}\" onblur=\"if(this.value==''){this.value=this.defaultValue;this.style.color='#999999'}\"/><br>";
        echo "<input type=\"file\" name=\"input_fname\"><br>";
        echo "<textarea name=\"input_comment\" class=\"input_comment\" onfocus=\"if(this.value==this.defaultValue){this.value='';this.style.color='black';}\" onblur=\"if(this.value==''){this.value=this.defaultValue;this.style.color='#999999'}\" >コメント</textarea><br>";
        echo "<input type=\"submit\" name=\"send\" value=\"書き込む\" class=\"input_com_button\" id=\"lastcom\" />";
        echo "</form>";
        echo "</div>";

        echo "</div>";

        /**********************************/
        /*         スレ作成エリア         */
        /*                (2)             */
        /*          レンダリング          */
        /**********************************/
        echo "<div style=\"border: 1px solid #3399FF;\" class=\"make_sled_area\">";
        echo "<div class=\"explain_block\">";
        echo "<h2 style=\"margin:0;\">ルール</h2>";
        echo "<ul class=\"explain_list\"><li>書き込めるのは現状テキストのみ</li><li>荒らしたら負け</li></ul>";
        echo "</div>";

        echo "<div class=\"make_sled_block\">";
        echo "<form method=\"post\" action=\"\">";
        echo "<input type=\"text\" name=\"make_sled_input_sleti\" value=\"スレッド名\" class=\"make_sled_input_sleti\" onfocus=\"if(this.value==this.defaultValue){this.value='';this.style.color='black';}\" onblur=\"if(this.value==''){this.value=this.defaultValue;this.style.color='#999999'}\"/><br>";
        echo "<input type=\"submit\" name=\"send_sle\" value=\"スレッドを立てる\" class=\"button_sle\" />";
        echo "</form>";
        echo "</div>";

        echo "</div>";

        echo "<div class=\"backtop\">";
        echo "<a href=\"#\">ページ上部へ移動</a>";
        echo "</div>";
?>
</body>
</html>
  • 18~29行:タイトル取得
    • 108~114行:ページタイトルレンダリング
  • 38~66行:コメント入力用POSTデータをチェックしあれば作成済みのコメントテーブルに行を追加し、title_tableテーブルの該当する最終コメント日時を更新する。

2つのファイルの機能差分はそんなにありません。

スタイルシート

自分は動けばいいやの精神なので、この辺は好みでお願いします。

$ vi php/css/style.css
/************************/
/*スレタイ・コメント部分*/
/************************/
body {
    font-size:22px;
}

.sleti_area {
    margin-left:15%;
    margin-right:15%;
    margin-bottom:50px;
    margin-top:50px;
    padding:20px;
    white-space: nowrap;
    overflow:scroll;
    height:350px;
}

.slti {
        margin:0;
}


.comment_area {
    margin-left:15%;
    margin-right:15%;
    margin-bottom:50px;
    padding:20px;
    font-size:20px;
}

.comment_header {
    margin:0;
    font-size:15px;
}

.comment {
    margin-top:0;
    margin-bottom:30px;
}

/************************/
/*スレタイ・コメント部分*/
/************************/
.explain_block {
    text-align:center;
    margin-bottom:30px;
    margin-bottom:30px;
}

.explain_list {
    text-align:left;
}

/************************************************************************/
/*                               POST部分                               */
/*input系は要素定義が特殊でuser-agent stylesheetを呼ぶので個別に指定する*/
/************************************************************************/
.input_com_block {
    text-align:center;
}

.input_name {
    margin-bottom:20px;
    font-size:20px;
    padding:5px;
}

.input_fname {
    margin-bottom:20px;
    font-size:20px;
}

.input_comment {
    margin-bottom:20px;
    font-size:20px;
    padding:5px;
    width:70%;
    height:300px;
}

.input_com_button {
    margin-bottom:20px;
    font-size:20px;
    width:70%;
}

.make_sled_area {
    margin-left:15%;
    margin-right:15%;
    margin-bottom:50px;
    padding:20px;
}

.make_sled_block {
    text-align:center;
}

.make_sled_input_sleti {
    margin-bottom:20px;
    font-size:20px;
    padding:5px;
    width:70%;
}

.button_sle {
    margin-bottom:20px;
    font-size:20px;
    width:70%;
}

.backtop {
    text-align:center;
}

コンテナ起動

以上で開発は完了です。あとはdocker環境を用意して実行してください。

1. docker-compose.ymlファイルのあるディレクトリに移動する。
# docker-compose up -d

2. mysqlコンテナ上でinit-database.shを実行する。

あとはfirewallやポート開放などを行ってください。

  • 80/tcp
  • 3306/tcp

最後に

勉強不足なもので至らない点が多かったかと思います。それでも最後までお読みいただきありがとうございました。

本当は証明書取得やテキスト以外の書込み機能、改行対応、絵文字、XSS対策などやらないといけないことは山ほどあります。ですが掲示板という機能のみを考えれば実装することは出来ます。今回の記事を少しでも面白いと思って頂ければ幸いです。

また今挙げたものもそれほど難しいものではないので是非対応してみてはいかがでしょうか。証明書などは普段意識していない分、意外と勉強になります。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA