Quetzall AI Lab ヒーローヘッダー

Quetzall AI Lab

【サイト拡張】学習時間ログのバーチャート作成
 ~学習時間入力フォームの作成~

thumbnail_img

全体構想のとおり、学習時間を記録・表示するものを作成しました。この記事では学習時間をWebフォームから入力して、SQLite3 データベースへ追加するまでのシステムを説明します。

目次

  1. 全体の構成・フローチャート
  2. データベースで保管するデータについて
  3. フォーム要素 全体フレームの作成
    1. input_study_time.php
  4. フォーム要素 HTMLファイル作成
    1. input_form.html (フォーム要素)
    2. input_complete.html (送信完了案内)
  5. フォーム要素 PHPファイル作成
    1. input_database.php (データベースへの入力)
  6. フォーム要素 JavaScriptファイル作成
    1. script-date.js

1. 全体の構成・フローチャート

まず、以下左図上図がシステムのファイル階層となります。studylogフォルダ内のinput_study_time.phpに、local_htmlフォルダ内のフォーム要素input_form.htmlやフォーム送信完了画面input_complete.htmlを差し込むことで、ブラウザの表示画面を制御しています。フォームより送信されたデータは、local_phpフォルダ内のinput_database.phpによりデータベースlog.dbへ追加されます。
また、ブラウザからlog.dbへ学習時間を送信するフローチャートは以下右図の2つ目の図のようになります。学習記録を送信した直後に、続けて別の記録(別教材の記録)を送信する際、処理が分岐して再度入力フォームを表示するにようにします。

file_directory flow_chart

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>
                                
                            
  1. include "local_php/input_database.php"; は、input_database.php という別ファイルを読み込みます。このファイルには、フォームの送信内容をデータベースに保存する処理が含まれています。フォームの送信ボタンが押された場合、このスクリプトが実行されます。
  1. if(isset($_POST["submit1"])) { ... } は、フォームが送信されたかどうかを確認します。$_POST はフォームのデータを取得するスーパーグローバル変数です。submit1 はフォームの送信ボタン名です
  1. include "local_html/input_complete.html"; は、フォームが送信された場合に送信完了画面を表示するためのHTMLファイルを読み込みます。
  1. 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へ記録するプログラムを作成します。
全体の流れは以下の通りです。

  1. 日本のタイムゾーンを設定する
  2. log.db という名前のデータベースファイルが存在するか確認する
  3. フォームが送信された場合に、log.dbを開き、存在していなければ新しいテーブルを作成する
  4. フォームから送信されたデータを変数に格納し、現在の日時を取得する
  5. 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();
                                        }
                                    ?>
                                    
                                
  1. date_default_timezone_set('Asia/Tokyo'); はPHPのデフォルトタイムゾーンを日本時間に設定します。
  2. $log_db = "log.db"; はデータベースファイルの名前を指定しています。
  1. file_exists($log_db); は、log.db というファイルが存在するかどうかを確認します。存在する場合は true を返し、存在しない場合は false を返します。
  1. if(isset($_POST["submit1"]) && ... ) は、フォームが送信されたかどうかを確認します。$_POST はフォームのデータを取得するスーパーグローバル変数です。すべてのフォーム項目(submit1, material, hour, minute, date)がセットされているか確認しています。
  1. new SQLite3($log_db); は、指定したデータベースファイルを開くか、新規作成します。
  1. if(!$ext) { ... } は、データベースファイルが存在しない場合に、新しいデータベーステーブルを作成します。
  1. $query にSQLクエリを格納します。
  2. $db->exec($query); でそのクエリを実行します。ここでは、study_log という名前のテーブルを作成しています。
  1. フォームから送信された学習日データを変数に格納します。
  1. フォームから送信された時間(hour)データを変数に格納します。
  2. フォームから送信された時間(minute)データを変数に格納します。
  1. フォームから送信された日付をタイムスタンプとして変数に格納します。
  1. フォームから送信された教材種別を変数に格納します。
  1. フォームのデータをデータベースに挿入するためのSQLクエリを $query に格納します。
  2. $db->exec($query); でそのクエリを実行します。
  1. $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を使いました。
全体の流れは以下の通りです。

  1. 現在の日付と時刻を取得。
  2. 取得した年、月、日を個別に変数に格納。
  3. これらの変数を結合して yyyy-mm-dd の形式に変換。
  4. 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;
                            
                        
  1. const now = new Date(); は、現在の日付と時刻を取得し、それを now という変数に格納します。
  2. now.getFullYear(); は、現在の年(例:2024年)を取得し、それを year という変数に格納します。
  3. now.getMonth() + 1; は、現在の月を取得し、それを month という変数に格納します。JavaScriptの月は0から始まるため、1を加えて通常の月の値にします(例:6月は5として取得されるので、+1して6とします)。
  4. now.getDate(); は、現在の日(例:28日)を取得し、それを date という変数に格納します。
  1. 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桁にします。
  1. console.log("現在は " + output); は、コンソールに現在の日付を表示します。これにより、開発者は日付が正しく取得され、形式が正しく変換されたかどうかを確認できます。a
  1. 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. 成果物

以下のように出来上がりました。*設問・選択肢が上記と若干異なっていますが、ご容赦ください。

コメント・お問合せ

以下のツイートの『返信』にてお願いいたします