LoginSignup
2
0

More than 3 years have passed since last update.

HTML・PHP・MySQLだけで作る間違い探しゲーム【⑥ランキングページを作る】

Last updated at Posted at 2020-10-26

6. ランキング表示ページ


<< 前の記事 【⑤結果表示ページを作る】
5. 結果表示ページ
  5-1. 無効なアクセスの拒否
  5-2. 回答時間の算出
  5-3. 各変数への格納
  5-4. 保存する回答時間とカウント数の上限設定
  5-5. 正解/不正解による表示メッセージの分岐
  5-6. ランキングへの登録
   5-6-1. ランキングテーブルの構成
   5-6-2. ランキングへの登録

最後に、回答時間ランキングを表示するページを実装します。

ランキングページ.png

ranking.php
<?php

// 難易度がPOSTされている場合は変数に格納
if (isset($_POST['show_method'])) {
    $select = $_POST['show_method'];
} else {
    $select = 'all';
}

// db接続
require_once('db_connect.php');

// 選択された表示形式によってSQL文を分岐
$sql = 'SELECT * FROM rankings ';
switch ($select) {
    case 'difficult':
        $sql .= "WHERE difficulty = '難しい(漢字)' ORDER BY time LIMIT 10";
        break;
    case 'easy':
        $sql .= "WHERE difficulty = '易しい(絵文字)' ORDER BY time LIMIT 10";
        break;
    case 'all':
        $sql .= 'ORDER BY time LIMIT 10';
        break;
}
$stmt = $dbh->query($sql);
$players = $stmt->fetchAll();

?>
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="style.css">
        <title>間違い探し ランキング</title>
    </head>
    <body>
        <h1>回答時間ランキング</h1>
        <form method="POST">
            <select name="show_method" size="1">
                <option value="all" <?php if ($select === 'all') echo 'selected' ?>>全て</option>
                <option value="easy" <?php if ($select === 'easy') echo 'selected' ?>>易しい</option>
                <option value="difficult" <?php if ($select === 'difficult') echo 'selected' ?>>難しい</option>
            </select>
            <input type="submit" value="表示">
        </form>
        <div class="table">
            <table class="s-tbl">
                <thead>
                    <tr>
                        <th>順位</th>
                        <th>名前</th>
                        <th>難易度</th>
                        <th>回答時間</th>
                        <th>リセット回数</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($players as $key => $player): ?>
                    <tr>
                        <td><?= ++$key; ?></td>
                        <td><?= $player['name']; ?></td>
                        <td><?= $player['difficulty']; ?></td>
                        <td><?= $player['time']; ?></td>
                        <td><?= $player['reset']; ?></td>
                    </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
        </div>
        <p>
            <button type="button" onclick="location.href='start.php'">スタートページへ</button>
        </p>
    </body>
</html>

6-1. 表示切り替え機能

ranking.php
// 難易度がPOSTされている場合は変数に格納
if (isset($_POST['show_method'])) {
    $select = $_POST['show_method'];
} else {
    $select = 'all';
}

// db接続
require_once('db_connect.php');

// 選択された表示形式によってSQL文を分岐
$sql = 'SELECT * FROM rankings ';
switch ($select) {
    case 'difficult':
        $sql .= "WHERE difficulty = '難しい(漢字)' ORDER BY time LIMIT 10";
        break;
    case 'easy':
        $sql .= "WHERE difficulty = '易しい(絵文字)' ORDER BY time LIMIT 10";
        break;
    case 'all':
        $sql .= 'ORDER BY time LIMIT 10';
        break;
}
$stmt = $dbh->query($sql);
$players = $stmt->fetchAll();

後述する<select>タグによって難易度を「全て」「易しい」「難しい」の選択肢の中から選べるようになっています。

if-else文によって選択されていた場合はそのvalueの値を、選択されていない場合(=初回訪問時)にはall$selectに格納させています。

そして、DB接続設定ファイルを呼び出し、$select内の値によってSQL文が変更されるようにswitch構文を用いています。

どの選択肢においてもSELECT * FROM rankingsは共通しているので、一旦$sqlにこの文を格納してから、条件分岐に応じたSQL文を結合代入演算子.=によって追加しています。

PHPマニュアル「PHP: 文字列演算子 - Manual

その後、query()メソッドによってSQL文を実行し、返ってきたPDOStatementオブジェクトを$stmtに格納し、次いでfetchAll()メソッドによって結果を$players配列として格納しています。

PHPマニュアル「PHP: PDOStatement::fetchAll - Manual

db_connect.php」でフェッチ形式をPDO::FETCH_ASSOCと指定したので、対象テーブルのカラム名がキーとなった配列として格納されています。

6-2. 入力値の保持 - <select>タグ

ranking.php
        <form method="POST">
            <select name="show_method" size="1">
                <option value="all" <?php if ($select === 'all') echo 'selected' ?>>全て</option>
                <option value="easy" <?php if ($select === 'easy') echo 'selected' ?>>易しい</option>
                <option value="difficult" <?php if ($select === 'difficult') echo 'selected' ?>>難しい</option>
            </select>
            <input type="submit" value="表示">
        </form>

start.php」のtextタイプやradioタイプの<input>タグと同じように、<select>タグでも入力値が保持されるようにしています。

これは$selecteの値に応じてselected属性を対象の<option>タグ内にechoさせることで実現できます。

6-3. ランキングの表示

6-3-1. テーブルの表示

ranking.php
        <div class="table">
            <table class="s-tbl">
                <thead>
                    <tr>
                        <th>順位</th>
                        <th>名前</th>
                        <th>難易度</th>
                        <th>回答時間</th>
                        <th>リセット回数</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($players as $key => $player): ?>
                    <tr>
                        <td><?= ++$key; ?></td>
                        <td><?= $player['name']; ?></td>
                        <td><?= $player['difficulty']; ?></td>
                        <td><?= $player['time']; ?></td>
                        <td><?= $player['reset']; ?></td>
                    </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
        </div>

find_the_mistake.php」と同様に、foreach構文によって配列となっている$playersのデータを<td>タグ内で出力しています。

foreach構文には、

  • foreach (array_expression as $value)
  • foreach (array_expression as $key => $value)

の2種類の構文があり、今回は後者を用いることで配列のインデックス番号$keyを取得し、順位を表現しています。

PHPマニュアル「PHP: foreach - Manual

順位は1から始まりますが、配列のインデックス番号は0から始まるので、プレインクリメント(前置加算子)<?= ++$key; ?>を用いることで、+1させてから出力しています1

PHPマニュアル「PHP: 加算子/減算子 - Manual

6-3-2. テーブルデザイン

style.css
.table {
  margin-top: 10px;
}
.s-tbl {
  border-collapse: collapse;
}
.s-tbl th, .s-tbl td {
  border: 1px solid #000;
  padding: 0.5em;
}
.s-tbl tr:nth-child(even) {
  background: #eee;
}
.s-tbl tr:hover {
  background: #ffffe0;
}

テーブルのCSSに関しては下記の記事から引っ張ってきたものに、少しだけ手を加えました。

ご参考までに。

いつか誰かの役に立つかもしれないweb制作屋の備忘録
css tableで背景色を交互に変える方法

これでようやく完成です!

ここまで読んでくださりありがとうございます。

何かおかしなところや改善できる点がございましたら、コメントいただけるとありがたいです!


<< 前の記事 【⑤結果表示ページを作る】
5. 結果表示ページ
  5-1. 無効なアクセスの拒否
  5-2. 回答時間の算出
  5-3. 各変数への格納
  5-4. 保存する回答時間とカウント数の上限設定
  5-5. 正解/不正解による表示メッセージの分岐
  5-6. ランキングへの登録
   5-6-1. ランキングテーブルの構成
   5-6-2. ランキングへの登録


  1. インクリメントデクリメントにはそれぞれプレ(前置)ポスト(後置)があり、それぞれ2連続の加算子/減算子が前と後に付きます($aへの加算なら++$a$a++)。これらは「変数返す前に加算/減算する」か「変数を返した後に加算/減算する」かといった違いがあり、今回のコードでポストインクリメント($key++)を用いてしまうとechoされた後に+1されてしまい、意味をなさなくなります。 

2
0
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
2
0