LoginSignup
0
1

More than 1 year has passed since last update.

プロジェクト型演習 #3 (DB作成, web画面)

Last updated at Posted at 2021-06-04

本番環境の構築

実際にシステムで使用するDBを作成する。
前提として プロジェクト型演習 #1 (raspberrypi DB操作) 実装済み、更に Apache2 をインストール済みののRaspberry Pi を利用しているものとして話を進める。
今回は、本番用DBを作成し、Web画面で確認するところまでやってみる。

DB構築

ログイン

面倒なので、以前作成したユーザ, DBを使い回す。

ユーザでログイン
pi@raspberry:~ $ sudo mysql -upi -praspberry
DBへ入る
MariaDB[(none)]> use sample_db
Database changed

各種テーブルの作成

※下記SQL文をそのままコピペでおけ。詳しくは #1 を参照。

スコアテーブルの作成
CREATE TABLE `score` (
  `num` int(32) NOT NULL AUTO_INCREMENT,
  `id` int(4) NOT NULL,
  `score` int(8) NOT NULL,
  `great` int(4) NOT NULL,
  `good` int(4) NOT NULL,
  `bad` int(4) NOT NULL,
  `datetime` DATETIME NOT NULL,
  PRIMARY KEY (`num`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
楽曲テーブルの作成
CREATE TABLE `music` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` varchar(512) NOT NULL,
  `max` int(8) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
楽曲テーブルにデータを挿入
INSERT INTO `music` (`name`, `max`) VALUES
("ピタゴラスイッチ", 1000),
("きらきら星", 1000);
スコアテーブルにデータを挿入
INSERT INTO `score` (`id`, `score`, `great`, `good`, `bad`, `datetime`) VALUES
(1, 305, 25, 51, 24, '2021-06-01 21:45:31'),
(1, 700, 50, 40, 10, '2021-06-02 21:45:31'),
(2, 625, 40, 45, 15, '2021-06-03 21:45:31'),
(1, 125, 5, 15, 80, '2021-06-03 21:45:31');

WEB画面 (PHP)

TOPページ

今後修正予定だが、雑に作っておく。
以下の全ファイルを/var/www/html/内に配置。index.phpは前回作成したものを修正する。

pi@raspberry:~ $ cd /var/www/html
pi@raspberry:/var/www/html $ nano index.php

TOP
index.php
<?php
    $title = "認知症予防システム";
    require('./header.php');
    $page = "home";
?>
    <h1 class="mx-auto" style="width: 200px; font-family: ヒラギノ丸ゴ ProN W4;">スコア表</h1>
    <table class="table">
        <thead class="table-light" style="background-color: #008b8b;">
            <th>日付</th>
            <th>曲名</th>
            <th>スコア</th>
            <th>GREAT</th>
            <th>GOOD</th>
            <th>BAD</th>
            <th>%</th>
        </thead>
<?php
    ini_set('display_errors', "On");
    //phpinfo();
    include "./pdo_connect.php";
    $sql = "SELECT * FROM score JOIN music WHERE score.id = music.id ORDER BY score.datetime DESC";
    $stmt = $pdo -> query($sql);
    foreach($stmt as $row){
?>
        <tbody id = "<?=$row['num']?>">
            <td><?=date('Y年m月d日 H:i',strtotime($row['datetime']))?></td>
            <td><?=$row['name']?></td>
            <td><?=$row['score']?></td>
            <td><?=$row['great']?></td>
            <td><?=$row['good']?></td>
            <td><?=$row['bad']?></td>
            <td><?=($row['score'] / $row['max']) * 100?></td>
        </tbody>
<?php
    }
?>
    </table>
<?php
    require('./footer.php');
?>

ヘッダーファイル

pi@raspberry:/var/www/html $ nano header.php

ヘッダーファイル
header.php
<!DOCTYPE html>
<html lang='ja'>
<head>
    <meta charset='utf-8' />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
    <title><?=$title?></title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@5.5.0/main.min.css">
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.5.0/main.min.js"></script>
</head>
<body>
<nav class="navbar navbar-dark mb-5" style="background-color: #008080;">
  <a class="navbar-brand" href="./index.php">認知症予防システム</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarNavAltMarkup">
    <div class="navbar-nav">
      <a id="home" class="nav-item nav-link" href="./index.php">Home <span class="sr-only">(current)</span></a>
      <a id="calendar" class="nav-item nav-link" href="./calendar.php">Calendar</a>
      <a id="graph" class="nav-item nav-link" href="./graph.php">Graph</a>
    </div>
  </div>
</nav>
<div class="container w-80">

フッターファイル

pi@raspberry:/var/www/html $ nano footer.php

フッターファイル
footer.php
</div>
</body>
</html>
<script>
const div = document.getElementById("<?=$page?>");
div.classList.add('active');
</script>

カレンダー

pi@raspberry:/var/www/html $ nano calendar.php

カレンダー
calendar.php
<?php
    $title = "カレンダー";
    require('./header.php');
    $page = "calendar";
?>
<div id='calendar-box'></div>
<?php
    require('./footer.php');
?>
<script>
document.addEventListener('DOMContentLoaded', function() {
    var calendarEl = document.getElementById('calendar-box');
    var calendar = new FullCalendar.Calendar(calendarEl, {
        initialView: 'dayGridMonth',
        events: [
<?php
include "./pdo_connect.php";
$sql = "SELECT * FROM score JOIN music WHERE score.id = music.id";
$stmt = $pdo -> query($sql);
foreach($stmt as $row){
?>
                {
                    id: '<?=$row['num']?>',
                    title: '<?=$row['name']." ".$row['score']?>',
                    start: '<?=date('Y-m-d',strtotime($row['datetime']))?>',
                    url: './index.php#<?=$row['num']?>'
                },
<?php
}
?>

        ],
        // 日本語化
        locale: 'ja',
        buttonText: {
            prev:     '<',
            next:     '>',
            prevYear: '<<',
            nextYear: '>>',
            today:    '今日',
            month:    '',
            week:     '',
            day:      '',
            list:     '一覧'
        },
    });
    calendar.render();
});
</script>

グラフ

pi@raspberry:/var/www/html $ nano graph.php

グラフ
graph.php
<?php
    $title = "グラフ";
    require('./header.php');
    $page = "graph";
    $labels = [];
    $datetime_list = [];
    for ($i = 6; $i >= 0; $i--) {
        $m = (int)date("m", strtotime("-"."$i"." day"));
        $d = (int)date("d", strtotime("-"."$i"." day"));
        $labels[] = $m."月".$d."日";
        $datetime_list[] = date("Y-m-d", strtotime("-"."$i"." day"));
    }
    $start = date("Y-m-d", strtotime("-6 day"));
    $start .= " 00:00:00";
    $end = date("Y-m-d", strtotime("-0 day"));
    $end .= " 99:99:99";

    include "./pdo_connect.php";
    $sql = "SELECT * FROM score JOIN music WHERE score.id = music.id AND score.datetime BETWEEN '$start' AND '$end' ORDER BY score.datetime ASC";
    $stmt = $pdo -> query($sql);
    $cnt = 0;
    $max_list = [0, 0, 0, 0, 0, 0, 0];
    $min_list = [200, 200, 200, 200, 200, 200, 200];
    foreach($stmt as $row){
        for ($i = $cnt; $i < 7; $i++) {
            if ($datetime_list[$i]." 00:00:00" <= $row['datetime'] && $row['datetime'] <= $datetime_list[$i]." 99:99:99") {
                if ($max_list[$cnt] < ($row['score'] / $row['max']) * 100) {
                    $max_list[$cnt] = ($row['score'] / $row['max']) * 100;
                }
                if ($min_list[$cnt] > ($row['score'] / $row['max']) * 100) {
                    $min_list[$cnt] = ($row['score'] / $row['max']) * 100;
                }
                break;
            } else {
                $cnt ++;
            }
        }
    }
    for ($i = 0; $i < 7; $i++) {
        if ($min_list[$i] == 200) {
            $min_list[$i] = 0;
        }
    }
?>
<h1>折れ線グラフ</h1>
  <canvas id="myLineChart"></canvas>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>

  <script>
  var ctx = document.getElementById("myLineChart");
  var myLineChart = new Chart(ctx, {
    type: 'line',
    data: {
        labels: ['<?=$labels[0]?>', '<?=$labels[1]?>', '<?=$labels[2]?>', '<?=$labels[3]?>', '<?=$labels[4]?>', '<?=$labels[5]?>', '<?=$labels[6]?>'],
      datasets: [
        {
          label: '最高得点率(%)',
          data: [<?=$max_list[0]?>, <?=$max_list[1]?>, <?=$max_list[2]?>, <?=$max_list[3]?>, <?=$max_list[4]?>, <?=$max_list[5]?>, <?=$max_list[6]?>],
          borderColor: "rgba(255,0,0,1)",
          backgroundColor: "rgba(0,0,0,0)"
        },
        {
          label: '最低得点率(%)',
          data: [<?=$min_list[0]?>, <?=$min_list[1]?>, <?=$min_list[2]?>, <?=$min_list[3]?>, <?=$min_list[4]?>, <?=$min_list[5]?>, <?=$min_list[6]?>],
          borderColor: "rgba(0,0,255,1)",
          backgroundColor: "rgba(0,0,0,0)"
        }
      ],
    },
    options: {
      title: {
        display: true,
        text: '得点率(<?=$labels[0]?> ~ <?=$labels[6]?>'
      },
      scales: {
        yAxes: [{
          ticks: {
            suggestedMax: 100,
            suggestedMin: 0,
            stepSize: 10,
            callback: function(value, index, values){
              return  value +  '%'
            }
          }
        }]
      },
    }
  });
  </script>
<?php
    require('./footer.php');
?>

DB接続ファイル

pi@raspberry:/var/www/html $ nano pdo_connect.php

DB接続ファイル
pdo_connect.php
<?php
//データベースの接続と選択
$hostdbname = 'mysql:host=localhost;dbname=sample_db;charset=UTF8';
$username = "pi";
$password = "raspberry";
$pdo = new PDO($hostdbname, $username, $password);
$pdo -> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
?>

実行

おそらくこんな感じでできるはず、、、
※この画像はPC上にDockerで環境構築したものを使用している為、実際とは異なる。

今後

  • TOPページの装飾
  • 検索機能やランキング、ソートなんかの実装(余力あれば)
0
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
0
1