6. ランキング表示ページ
<< 前の記事 [【⑤結果表示ページを作る】](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5)
[5. 結果表示ページ](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-結果表示ページ) [5-1. 無効なアクセスの拒否](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-1-無効なアクセスの拒否) [5-2. 回答時間の算出](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-2-回答時間の算出) [5-3. 各変数への格納](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-3-各変数への格納) [5-4. 保存する回答時間とカウント数の上限設定](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-4-保存する回答時間とカウント数の上限設定) [5-5. 正解/不正解による表示メッセージの分岐](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-5-正解不正解による表示メッセージの分岐) [5-6. ランキングへの登録](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-6-ランキングへの登録) [5-6-1. ランキングテーブルの構成](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-6-1-ランキングテーブルの構成) [5-6-2. ランキングへの登録](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-6-2-ランキングへの登録)最後に、回答時間ランキングを表示するページを実装します。
<?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. 表示切り替え機能
// 難易度が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>
タグ
<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. テーブルの表示
<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. テーブルデザイン
.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で背景色を交互に変える方法」
これでようやく完成です!
ここまで読んでくださりありがとうございます。
何かおかしなところや改善できる点がございましたら、コメントいただけるとありがたいです!
<< 前の記事 [【⑤結果表示ページを作る】](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5)
[5. 結果表示ページ](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-結果表示ページ) [5-1. 無効なアクセスの拒否](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-1-無効なアクセスの拒否) [5-2. 回答時間の算出](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-2-回答時間の算出) [5-3. 各変数への格納](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-3-各変数への格納) [5-4. 保存する回答時間とカウント数の上限設定](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-4-保存する回答時間とカウント数の上限設定) [5-5. 正解/不正解による表示メッセージの分岐](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-5-正解不正解による表示メッセージの分岐) [5-6. ランキングへの登録](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-6-ランキングへの登録) [5-6-1. ランキングテーブルの構成](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-6-1-ランキングテーブルの構成) [5-6-2. ランキングへの登録](https://qiita.com/_Taturon_/items/b3eb00e4c3ea52f0b6b5#5-6-2-ランキングへの登録)-
インクリメント・デクリメントにはそれぞれ**プレ(前置)とポスト(後置)**があり、それぞれ2連続の加算子/減算子が前と後に付きます(
$a
への加算なら++$a
と$a++
)。これらは「変数返す前に加算/減算する」か「変数を返した後に加算/減算する」かといった違いがあり、今回のコードでポストインクリメント($key++
)を用いてしまうとecho
された後に+1
されてしまい、意味をなさなくなります。 ↩