サイトアイコン プログラミングを学習中の私が、アウトプットするためのサイト

PHPとSqliteとJavaScriptを使って勝敗を管理してみる

このページではソースコードの一部分を簡単な解説をしています。
サンプルのソースコードはgithubにあります。

スポンサーリンク

概要

いままで作成したゲームの中で三目並べなどコンピューターと対戦できるゲームの戦績を管理する表を作りました。データベースはSqlite、データベースの接続にはPHP、HTMLへ表示させるためのDOM操作はJavaScriptでしました。↓のプログラムは今回実装した勝敗表のプログラムを利用したサンプルです。手番と勝敗を選択して送信ボタンを押すと戦績表に反映されます。

勝敗表を実装した過去のゲーム↓

Visual Studio Codeの拡張機能SQliteを使用してデータベースを作成する

データベースの作成にはVisual Studio Codeの拡張機能SQliteを使用しました。

テーブル名はtestにしました。テーブルの中には五つのカラムがあり、一つ目はプライマリキー、二つ目のturnは手番、残りのwin、lose、drawには勝ち、負け、引き分けの数をそれぞれ保持します。

CREATE TABLE test(id INTEGER PRIMARY KEY, turn TEXT, win INTEGER, lose INTEGER, draw INTEGER);

INSERT INTO test VALUES(0, '先手', 0, 0, 0);
INSERT INTO test VALUES(1, '後手', 0, 0, 0);

PHPのPDOを使ってデータベースに接続してデータを取得する

PDOクラスをインスタンス化する

// pdoインスタンス生成
function getPdoInstance()
{
try{
    $pdo = new PDO('sqlite:./test.db'); //  PDOの引数に(sqlite:データベースのパス)で指定する
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // エラーが起きた時例外を投げる
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); // 連想配列形式でデータを取得する
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // 指定した型に合わせる

    return $pdo;
    
    }catch(PDOException $e){
    //echo $e->getMessage();
    exit('エラーが発生しました');
    }
}

$pdo = getPdoInstance();

PDOクラスの引数にデータベースファイルが置いてあるパスを指定します。これでデータベースの接続は完了です。必要に応じてsetAttributeメソッドで属性をセットします。今回は3つ属性をセットしました。

queryメソッドを使用して必要なデータを取得する。

// データ取得
function getDb($pdo)
{
    $stmt = $pdo->query("SELECT id, turn, win, lose, draw FROM test UNION SELECT 3, '通算', SUM(win), SUM(lose), SUM(draw) FROM test");
    $stmts = $stmt->fetchAll();
    return $stmts;
}

$json = getDb($pdo);
$data=json_encode($json);
echo $data;

UNION句を使用して通算成績の行を作成し、fetchAllメソッドでデータを取得しています。取得したデータはjson_encodeメソッドでjson形式にエンコードしています。

JavaScriptのFetch APIを使ってサーバーにリクエストする

先ほどPHPで作成したjsonをJavaScriptのFetchAPIを使用して取得します。

// 取得
function fetchResult() {
  return fetch("./grades.php")
    .then((response) => response.json())
    .then((data) => {
      return data;
    })
    .catch((error) => {
      console.log(error);
      return;
    });
}

DOMを操作してHTMLにレンダリングする。

// 表示
const grades = document.getElementById("grades");

fetchResult().then((data) => {
  Object.keys(data).forEach((key) => {
    const tr = document.createElement("tr");
    const th = document.createElement("th");
    const td = document.createElement("td");

    th.textContent = <code>${data[key].turn};
    tr.appendChild(th);
    td.textContent = ${data[key].win};
    tr.appendChild(td);
    const td2 = document.createElement("td");
    td2.textContent = ${data[key].lose};
    tr.appendChild(td2);
    const td3 = document.createElement("td");
    td3.textContent = ${data[key].draw};
    tr.appendChild(td3);
    grades.appendChild(tr);
  });
});

データベースへデータを追加する

サンプルプログラムの送信ボタンが押されるとサーバーへリクエストされます。先手番が選択されていたら0、後手番なら1の値を勝敗に関しても勝ちなら1負けなら0引き分けは2の数値をサーバーへ送信しています。

// 送信
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
  const turn = document.querySelector(".turn").value;
  const result = document.querySelector(".result").value;
  sendResult(turn, result);
});

// 登録
function sendResult(turn, result) {
  const fd = new FormData();
  fd.append("turn", turn);
  fd.append("result", result);
  fetch("./grades.php", {
    method: "POST",
    body: fd,
  })
    .then((response) => console.log(response))
    .then((data) => console.log(data))
    .then(location.reload())
    .catch((error) => {
      console.log(error);
    });
}

PHPでデータベースへデータの登録。

// データ登録
if($_SERVER['REQUEST_METHOD'] === 'POST')
{
    // 先手か後手か 0=先行 1=後攻
    $turn = filter_input(INPUT_POST, 'turn');
    // 勝敗の結果 0=負け 1=勝ち 2=引き分け
    $result = filter_input(INPUT_POST, 'result');
    $sql; 

    if($result == 1){
        $sql = "UPDATE test SET win = win + 1 WHERE id = ?";
    }elseif($result == 0){
        $sql = "UPDATE test SET lose = lose + 1 WHERE id = ?";
    }elseif($result == 2){
        $sql = "UPDATE test SET draw = draw + 1 WHERE id = ?";
    }

    $stmt = $pdo->prepare($sql);
    $stmt->execute([$turn]);
    
    exit;
}

JavaScriptからリクエストされたデータをprepareメソッドを使いクエリを送信して追加します。 勝敗に応じたクエリを用意し、手番はプレースホルダーを使用して値をセットしました。

最後までお読みいただきありがとうございました。
サンプルのソースコードはgithubにあります。

モバイルバージョンを終了