

【サイト拡張】学習時間ログのバーチャート作成
~学習時間入力フォームの作成~
全体構想のとおり、学習時間を記録・表示するものを作成しました。この記事では学習時間をWebフォームから入力して、SQLite3 データベースへ追加するまでのシステムを説明します。
目次
1. 全体の構成・フローチャート
まず、以下左図上図がシステムのファイル階層となります。studylogフォルダ内のinput_study_time.phpに、local_htmlフォルダ内のフォーム要素input_form.htmlやフォーム送信完了画面input_complete.htmlを差し込むことで、ブラウザの表示画面を制御しています。フォームより送信されたデータは、local_phpフォルダ内のinput_database.phpによりデータベースlog.dbへ追加されます。
また、ブラウザからlog.dbへ学習時間を送信するフローチャートは以下右図の2つ目の図のようになります。学習記録を送信した直後に、続けて別の記録(別教材の記録)を送信する際、処理が分岐して再度入力フォームを表示するにようにします。
2. データベースで保存しておくデータについて
今回、学習時間を保存・管理するデータベースは 他のSQLを使いこなせていないので SQLite3を利用しています。記録するデータは、以下5つです。
- 教材種別
- 学習した日
- 学習時間(Hour)
- 学習時間(minute)*10分単位
- データ登録日*フォーム送信ボタンを押した日時
3. フォーム要素 全体フレームの作成
input_study_time.php (全体フレーム)
1.で触れたように、ベースとなるinput_study_time.phpに差し込むHTMLファイルを変更することにより、入力から送信完了案内までを制御しています。コードは次のようになります。
<?php
// フォームの送信ボタンが押されたら、フォーム内容をデータベースに追加する
include "local_php/input_database.php";
?>
<!DOCTYPE html>
<html lang="ja">
<body>
<div>
<?php
// 条件により表示する画面を変更する
if(isset($_POST["submit1"])) {
// 送信完了画面の差し込み
include "local_html/input_complete.html";
} else {
// インプットフォームの差し込み
include "local_html/input_form.html";
}
?>
</div>
</body>
<script src="local_scripts/script_date.js"></script><!-- ローカルJavaScript 記録日のデフォルト値を当日に設定 -->
</html>
- include "local_php/input_database.php"; は、input_database.php という別ファイルを読み込みます。このファイルには、フォームの送信内容をデータベースに保存する処理が含まれています。フォームの送信ボタンが押された場合、このスクリプトが実行されます。
- if(isset($_POST["submit1"])) { ... } は、フォームが送信されたかどうかを確認します。$_POST はフォームのデータを取得するスーパーグローバル変数です。submit1 はフォームの送信ボタン名です
- include "local_html/input_complete.html"; は、フォームが送信された場合に送信完了画面を表示するためのHTMLファイルを読み込みます。
- include "local_html/input_form.html"; は、フォームが送信されていない場合に入力フォームを表示するためのHTMLファイルを読み込みます。
3行目のinclude "local_php/input_database.php";は、別ファイル input_database.php を読み込みます。このファイルでは、16行目で読み込まれたフォームから送信されたデータをlog.dbに保存する処理を行います。フォームの送信ボタンが押された場合、このスクリプトが実行されます。詳細は 5. をご参照ください。
11行目のif(isset($_POST["submit1"])) { ... } では、フォームが送信されたかどうかを確認します。
フォームが送信されていない段階(学習データを入力する段階)では、16行目のinclude "local_html/input_form.html";により入力フォームを表示します。
フォームを入力・送信されると13行目のinclude "local_html/input_complete.html";により送信が完了したことを表示します。
4. フォーム要素 HTMLファイル作成
i. input_form.html(フォーム要素)
2.のデータを入力するフォームを作成します。log.dbに保存する項目を設問として設置していきます。今回のフォームでは、教材種別、時間、分の項目を記録するにあたり、リスト選択形式である selectタグとoptionタグを使用しました。選択肢のタグは、可能であればPHPやJavascriptを使って自動で表示させると収集ミスの防止と、保守性の観点からもよいと思います。また、本記事では単純化してベタ打ちしていますが、教材選択肢のvalueは、RDBMSで正規化しておくと管理がしやすいと思います。
学習日時の登録 <input type="date">では、デフォルトで登録日(ブラウザでフォームを開いた日)が入力されるようにしたかったため、JavaScriptを利用して設定するようにしました。詳細は 6. をご参照ください。
<form name="input_study_time_register_form" action="input_study_time.php" method="post">
<h1>学習時間入力フォーム</h1>
<p>種別: <select name="material" >
<option value="materialA">教材A</option>
<option value="materialB">教材B</option>
<option value="materialC">教材C</option>
</select></p>
<p>時間: <select name="hour" >
<option value="0">0</option>
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select></p>
<p>分: <select name="minute" >
<option value="0">0</option>
<option value="10">10</option>
<option value="20">20</option>
<option value="30">30</option>
<option value="40">40</option>
<option value="50">50</option>
</select></p>
<p>日時: <input id="input_date" type="date" name="date"></p>
<p><input type="submit" name="submit1" value="送信"></p>
</form>
各設問にてname属性で記録する種別を、valueで選択された項目のデータ値を取得しています。例えば設問 種別: で 教材B を選択した場合は、学習した教材種別として教材Bを記録することとなります。設問の 時間: と 分:、日時: も同様です。
ii. input_complete.html(送信完了案内)
4-i. のフォームにて、データ送信処理が完了したことを表示するファイルです。記録した内容を確認するために$_POST[' ... ']にて送信した各設問の値を確認できるようにしました。
<p>お疲れ様でした。
以下を記録しました。<br>
material_id:<?php print "{$_POST['material']}"; ?><br>
hour:<?php print "{$_POST['hour']}"; ?><br>
minute:<?php print "{$_POST["minute"]}"; ?></p>
<form name="input_study_time_after_registered" action="input_study_time.php" method="post">
<p><input type="submit" name="back" value="前に戻る"></p>
</form>
5. フォーム要素 PHPファイル作成
i. input_database.php(データベースへの入力)
4-i. で入力されたデータを、データベースlog.dbへ記録するプログラムを作成します。
全体の流れは以下の通りです。
- 日本のタイムゾーンを設定する
- log.db という名前のデータベースファイルが存在するか確認する
- フォームが送信された場合に、log.dbを開き、存在していなければ新しいテーブルを作成する
- フォームから送信されたデータを変数に格納し、現在の日時を取得する
- log.dbにデータを挿入し、データベース接続を閉じる
コードの詳細は以下となります。
<?php
//input_form.htmlから渡された学習時間をlog.dbへ登録する
date_default_timezone_set('Asia/Tokyo'); //日本のタイムゾーンに設定
$log_db = "log.db"; //データベース名
//ファイルが存在するか確認する
$ext = file_exists($log_db);
// 送信ボタンが押された時
if(isset($_POST["submit1"]) && isset($_POST["material"]) && isset($_POST["hour"]) && isset($_POST["minute"]) && isset($_POST["date"])) {
$db = new SQLite3($log_db); //データベースを開く
//ファイルがなければ、データベース・テーブルを作成する
if(!$ext) {
$query = "CREATE TABLE study_log(register_id integer primary key autoincrement, date date, hour varchar(1), minute varchar(2), register_date date, material_id integer)";
$result = $db->exec($query);
}
//学習日を変数$dateに格納する
$date = $_POST["date"];
//学習時間(hour・minute)を変数$and2,$ans3に格納する
$hour = $_POST["hour"];
$minute = $_POST["minute"];
//記録日時を取得する
$register_date = strval(date("Y-m-d H:i:s"));
// 教材種別を変数$materialに格納する
$material = $_POST["material"];
// SQLデータベースへフォーム内容を記録する
$query = "INSERT INTO study_log(date, hour, minute, register_date, material_id) VALUES ('$date', '$hour', '$minute', '$register_date', '$material')";
$result = $db->exec($query);
//データベースを閉じる
$db->close();
}
?>
- date_default_timezone_set('Asia/Tokyo'); はPHPのデフォルトタイムゾーンを日本時間に設定します。
- $log_db = "log.db"; はデータベースファイルの名前を指定しています。
- file_exists($log_db); は、log.db というファイルが存在するかどうかを確認します。存在する場合は true を返し、存在しない場合は false を返します。
- if(isset($_POST["submit1"]) && ... ) は、フォームが送信されたかどうかを確認します。$_POST はフォームのデータを取得するスーパーグローバル変数です。すべてのフォーム項目(submit1, material, hour, minute, date)がセットされているか確認しています。
- new SQLite3($log_db); は、指定したデータベースファイルを開くか、新規作成します。
- if(!$ext) { ... } は、データベースファイルが存在しない場合に、新しいデータベーステーブルを作成します。
- $query にSQLクエリを格納します。
- $db->exec($query); でそのクエリを実行します。ここでは、study_log という名前のテーブルを作成しています。
- フォームから送信された学習日データを変数に格納します。
- フォームから送信された時間(hour)データを変数に格納します。
- フォームから送信された時間(minute)データを変数に格納します。
- フォームから送信された日付をタイムスタンプとして変数に格納します。
- フォームから送信された教材種別を変数に格納します。
- フォームのデータをデータベースに挿入するためのSQLクエリを $query に格納します。
- $db->exec($query); でそのクエリを実行します。
- $db->close(); でデータベース接続を閉じます。
7行目の file_exists($log_db); は、log.db というファイルが存在するかどうかを確認します。存在する場合は true を返し、存在しない場合は false を返します。$ext=falseの場合は、14行目のスクリプトによってデータを記録・管理するするデータベースを新設します
10行目 if(isset($_POST["submit1"]) && ... ) は、フォームが送信されたかどうかを確認します。$_POST はフォームのデータを取得するスーパーグローバル変数です。すべてのフォーム項目(submit1, material, hour, minute, date) がセットされているか確認しています。
14行目 if(!$ext) { ... } は、データベースファイルが存在しない場合に、新しいデータベーステーブルを作成します。
$query にSQLクエリを格納し、$db->exec($query); でそのクエリを実行します。ここでは、study_log という名前のテーブルを作成しています。
19行目以降は4-i. から送付されたデータをデータベースへ保存するための処理です。27行目strval(date("Y-m-d H:i:s"));は記録した日時のタイムスタンプで、現在の日時を取得し、log.dbへ記録するために日付型から文字列型に変換します。
6. フォーム要素 JavaScriptファイル作成
i. script-date.js
フォームで学習日時を入力する際に、デフォルト値でフォームにアクセスした日を設定するために、次のJavaSriptを使いました。
全体の流れは以下の通りです。
- 現在の日付と時刻を取得。
- 取得した年、月、日を個別に変数に格納。
- これらの変数を結合して yyyy-mm-dd の形式に変換。
- HTMLフォームの日付入力欄に、変換した日付をデフォルト値として設定。
"use strict";
//本日日付を取得する
const now = new Date();
const year = now.getFullYear();//今年
const month = now.getMonth() + 1;//今月
const date = now.getDate();//本日
// SQLのdate型に従ってyyyy-mm-ddの形式に変換する
const output = year+"-"+month.toString().padStart(2, "0")+"-"+date.toString().padStart(2, "0");
// ブラウザにて、一応日付を確認
console.log("現在は " + output);
// フォームの日付入力欄(id="input_date")にデフォルト値として本日日付を入力する
document.getElementById("input_date").value = output;
- const now = new Date(); は、現在の日付と時刻を取得し、それを now という変数に格納します。
- now.getFullYear(); は、現在の年(例:2024年)を取得し、それを year という変数に格納します。
- now.getMonth() + 1; は、現在の月を取得し、それを month という変数に格納します。JavaScriptの月は0から始まるため、1を加えて通常の月の値にします(例:6月は5として取得されるので、+1して6とします)。
- now.getDate(); は、現在の日(例:28日)を取得し、それを date という変数に格納します。
- year + "-" + month.toString().padStart(2, "0") + "-" + date.toString().padStart(2, "0"); は、取得した年、月、日を結合して yyyy-mm-dd の形式に変換します。
- month.toString().padStart(2, "0") は、月の値を2桁にします。例えば、5月は "05" になります。
- date.toString().padStart(2, "0") も同様に、日の値を2桁にします。
- console.log("現在は " + output); は、コンソールに現在の日付を表示します。これにより、開発者は日付が正しく取得され、形式が正しく変換されたかどうかを確認できます。a
- document.getElementById("input_date").value = output; は、HTMLフォームの id が input_date である入力欄に、変換した日付 output をデフォルト値として設定します。
- document.getElementById("input_date") は、HTMLドキュメント内の id が input_date である要素を取得します。
- .value = output; は、その要素の値を output に設定します。
注意する点として、getMonth()は、0を基点として月を計算する(例えばgetMonth(20231215)は11月を返す)ため、1カ月分を加算しておくことです。上記、HTMLファイルでは month にて now.getMonth() + 1とすることで、当月が記録されるようにしています。
7. 成果物
以下のように出来上がりました。*設問・選択肢が上記と若干異なっていますが、ご容赦ください。
SQLとPHPの骨子は終わったかな
— Quetzall (@QuetzallLab) May 26, 2024
次はJavaScriptとHTMLで pic.twitter.com/1AcfFt3dY9


コメント・お問合せ
以下のツイートの『返信』にてお願いいたします