📝

Nginx + PHP + MariaDB を使って簡易掲示板を作る

8 min read

環境

  • Linux 5.4.0-77-generic
  • Ubuntu Server 20.04.2 LTS (Focal Fossa)
  • nginx/1.18.0 (Ubuntu)
  • PHP 7.4.3 (fpm-fcgi)
  • mysql Ver 15.1 Distrib 10.3.29-MariaDB

Nginx と PHP のインストールと設定

Nginx と PHP をインストールするには次のコマンドを実行します。

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install nginx php-fpm

ここでは PHP を利用できる最低限の設定を記述します。ファイル /etc/nginx/sites-availbale/main を作成します。

$ sudo vim /etc/nginx/sites-available/main
/etc/nginx/sites-available/main
server {
        listen 80 default_server;  # Listen するポートの設定
        listen [::]:80 default_server;  # IPv6 用
        server_name _;
        root /var/www/html;  # ドキュメントルート (ファイルを配置する場所)
        index index.php index.html;  # / で終わる URL の時に表示するファイル名

        location / {
                try_files $uri $uri/ =404;
        }

	# PHP 用の設定
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
        }
}

設定を有効にするためにシンボリックリンクを作成します。また、デフォルトの設定を無効にするためにデフォルトのシンボリックリンクを削除します。

$ sudo ln -s /etc/nginx/sites-available/main /etc/nginx/sites-enable/main
$ sudo rm /etc/nginx/sites-enable/default

設定に誤りがないことを検査し、Nginx を再起動します。

$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ sudo systemctl restart nginx

適当な HTML ファイルと PHP スクリプトを作成・配置します。また、Web ブラウザで表示できることを確認します。ブラウザでページを表示するには Web サーバが稼動しているマシンの IP アドレスをアドレスバーに入力します。

$ sudo vim /var/www/html/index.html
$ sudo vim /var/www/html/info.php
/var/www/html/index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>てすとぺーじ</title>
  </head>
  <body>
    <h1>てすとぺーじ</h1>
    <p>てすとだよ。</p>
  </body>
</html>
/var/www/html/info.php
<?php phpinfo();

表示イメージ
確認したところ

MariaDB のインストールと設定

MariaDB をインストールするには次のコマンドを実行します。

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install mariadb-server php-mysql

初期設定を行います。

$ sudo mysql_secure_installation 
		... (中略) ...
Enter current password for root (enter for none):    # [Enter] 押下
OK, successfully used password, moving on...
		... (中略) ...
Set root password? [Y/n]    # [Enter] 押下
New password:               # パスワード設定
Re-enter new password:      # 再入力
Password updated successfully!
		... (中略) ...
Remove anonymous users? [Y/n]    # [Enter] 押下
 ... Success!
		... (中略) ...
Disallow root login remotely? [Y/n]    # [Enter] 押下
 ... Success!
		... (中略) ...
Remove test database and access to it? [Y/n]    # [Enter] 押下
 - Dropping test database...
		... (中略) ...
Reload privilege tables now? [Y/n]    # [Enter] 押下
 ... Success!
		... (中略) ...
Thanks for using MariaDB!

掲示板システムの製作

ここでは、投稿者名と投稿内容に加えて投稿日時を記録することにします。

データべースの作成

掲示板用のデータべース bbs と書き込みのテーブル kakiko を作成します。次のように実行します。

$ sudo mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 60
Server version: 10.3.29-MariaDB-0ubuntu0.20.04.1 Ubuntu 20.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> CREATE DATABASE bbs;  # データべースの作成
Query OK, 1 row affected (0.001 sec)

MariaDB [(none)]> USE bbs;  # 使用データべースの変更
Database changed
MariaDB [bbs]> CREATE TABLE kakiko (  # テーブルの作成
    -> id int NOT NULL PRIMARY KEY AUTO_INCREMENT,
    -> name varchar(64) NOT NULL,
    -> msg varchar(4096) NOT NULL,
    -> date datetime NOT NULL
    -> );
Query OK, 0 rows affected (1.144 sec)

MariaDB [bbs]> DESC kakiko;  # テーブル内容の確認
+-------+---------------+------+-----+---------+----------------+
| Field | Type          | Null | Key | Default | Extra          |
+-------+---------------+------+-----+---------+----------------+
| id    | int(11)       | NO   | PRI | NULL    | auto_increment |
| name  | varchar(64)   | NO   |     | NULL    |                |
| msg   | varchar(4096) | NO   |     | NULL    |                |
| date  | datetime      | NO   |     | NULL    |                |
+-------+---------------+------+-----+---------+----------------+
4 rows in set (0.002 sec)

MariaDB [bbs]>  # ユーザに権限を付与
MariaDB [bbs]> GRANT SELECT,INSERT ON kakiko TO bbsuser@localhost IDENTIFIED BY 'bbspasswd';
Query OK, 0 rows affected (0.001 sec)

MariaDB [bbs]> QUIT   # 終了
Bye

PHP スクリプトの作成

ここでは役割に応じた 2 つの PHP スクリプトを作成します。それぞれ、投稿内容を表示するスクリプト (index.php)、新規投稿を記録するスクリプト (recv.php) となっています。

$ sudo mkdir /var/www/html/bbs
$ sudo vim /var/www/html/bbs/index.php
$ sudo vim /var/www/html/bbs/recv.php
/var/www/html/bbs/index.php
<?php
const dsn = 'mysql:host=localhost;dbname=bbs';
const dbuser = 'bbsuser';
const dbpass = 'bbspasswd';
const sql = 'SELECT id,name,msg,date FROM kakiko';

try {
  $pdo = new PDO(dsn, dbuser, dbpass);
  $stmt = $pdo->prepare(sql);
  $stmt->execute();
} catch (PDOException $e) {
  $error = $e->getMessage();
  die("Something Wrong ($error)");
}
?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>簡易掲示板</title>
  </head>
  <body>
    <h1>簡易掲示板</h1>
    <div>
<?php while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { ?>
      <div class="kakiko">
        <div class="kakiko_header">
          <span class="id"><?= $row['id'] ?>:</span>
          <span class="name"><?= htmlspecialchars($row['name']) ?></span>
        </div>
	<div>
          <pre class="msg"><?= htmlspecialchars($row['msg']) ?></pre>
        </div>
	<div class="date">
          <?= $row['date'] ?>
        </div>
      </div>
      <hr>
<?php } /* while */ ?>
    </div>
    <form action="./recv.php" method="POST">
      <fieldset>
        <legend>新規投稿</legend>
        <div>
          <label for="name">名前:</label>
          <input type="text" name="name" id="name">
        </div>
        <div>
          <label for="msg">投稿内容</label>
          <div>
            <textarea name="msg" id="msg" required></textarea>
          </div>
        </div>
        <hr>
        <input type="submit">
        <input type="reset">
      </fieldset>
    </form>
  </body>
</html>
/var/www/html/bbs/recv.php
<?php
const dsn = 'mysql:host=localhost;dbname=bbs';
const dbuser = 'bbsuser';
const dbpass = 'bbspasswd';
const sql = 'INSERT INTO kakiko (name,msg,date) VALUES (:name,:msg,:date)';

if ($_SERVER['REQUEST_METHOD'] !== 'POST')
  goto endp;
if (empty($_POST['msg']))
  goto endp;

try {
  $pdo = new PDO(dsn, dbuser, dbpass);
  $stmt = $pdo->prepare(sql);
  $stmt->bindValue(':name',
      empty($_POST['name']) ? 'Anonymous' : $_POST['name'], PDO::PARAM_STR);
  $stmt->bindValue(':msg', $_POST['msg'], PDO::PARAM_STR);
  $stmt->bindValue(':date', date('Y-m-d H:i:s'), PDO::PARAM_STR);
  $stmt->execute();
} catch (PDOException $e) {
  $error = $e->getMessage();
  die("Something Wrong ($error)");
}

endp:
header('HTTP/1.1 303 See Other');
header('Location: ./');

見た目は貧相ですが掲示板として動作するシステムが完成しました。


動作テスト


おわりに

おわりです。

製作した掲示板には CSS をあてがっていないので見た目が貧相でした。自作する場合は綺麗にデコレーションしてあげてください。