ページネーションを作ったきっかけ
PHPでページネーションを自作せよ!という課題が出ました。
簡単なページネーションのやり方はネットに大量に上がってるし、何か自分で考えた機能を一つ持たせてみたいと思い、参考にできるアイデアを探しがてらChromeのページネーションをポチポチしていると
「Goooooooooogle」という風に「o」がページの数だけ連続して、表示されているページの部分だけ赤くなるのが面白かったので、Chromeのページネーションを実装できるかチャレンジしてみたところ、とりあえずは実装できたっぽいので、記録として記事にしておこうと思いました。
実装
まずページネーションで表示するページ数と1ページあたりのリソース数を定数で持ちます。
// ページネーションで表示するページ数
const RANGE = 10;
// 1ページに表示するリソース数
const ITEM_COUNT = 5;
クエリパラメーターからページ数を取得し、ページング対象リソースの件数をSQLを発行し取得します。(SQLの記述は省略しています)
// クエリパラメーターからページ数を取得
$page = $_GET['page'];
// "SQLの結果" -> 例) 77 (ページネーション対象リソースの件数)
$total = "SQLの結果";
表示できる最大ページ数を 件数 / 1ページに表示するリソース数
で求めます。
// 例) 77 / 5 を切り上げ -> 16
$maxPage = (int)ceil($total / ITEM_COUNT);
ページ数はクエリパラメーターから取得するため、URLを操作されて存在しないページ数が送信されてくる可能性があります。
そのため表示できる 最大ページ数よりも大きい値、もしくは1より小さい値
を取得した場合は1ページ目を表示します。
if ($page > $maxPage || $page < 1) {
$page = 1;
}
ここからはHTMLのfor文で使用する値の準備をします。
for文の初期値(startPage)は、ページネーションの最終ページ(endPage)からRANGE - 1を引いた値とします。
Chromeでは7ページ目からページネーションに表示されている数字が変わります。表示が 2 ~ 11ページになりました。
7ページ目からということは、「RANGE(10) / 2 + 1
」6ページより大きい場合は最終ページに「page(7) + floor((RANGE - 1) / 2)(4)
」11ページを設定します。
// 最終ページ = 7 > 6 ? 11 : 10
$endPage = $page > RANGE / 2 + 1 ? (int)($page + floor((RANGE - 1) / 2)) : RANGE;
最終ページの値は、表示できる最大ページ数よりも大きくなってしまう場合があるので、表示できる最大ページ数は超えないように調整します。
$endPage = min($endPage, $maxPage);
ページネーションに表示する最初のページ数を求めます。
こちらも最初のページが1より小さくならないよう調整します。
$startPage = max($endPage - (RANGE - 1), 1);
ここまででページネーションを表示するために必要な値の準備は整いました。
サンプルHTML
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
.bold {
font-weight: bold;
}
</style>
</head>
<body>
<div class="pagination bold">
<p>
<span>
<?php if ($page > 1) { ?>
<a href="/paginate?page=<?= $page - 1 ?>">< </a>
<?php } ?>
</span>
<span style="color: #4285f4;">G</span>
<?php for ($i = $startPage; $i <= $endPage; $i++) { ?>
<span style="color: <?= $i == $page ? "#ea4335" : "#fbbc05" ?>;">a</span>
<?php if ($i + 1 > $maxPage) {
break;
} ?>
<?php } ?>
<span style="color: #4285f4;">g</span>
<span style="color: #34a853;">l</span>
<span style="color: #ea4335;">e</span>
<span>
<?php if ($page < $maxPage) { ?>
<a href="/paginate?page=<?= $page + 1 ?>"> ></a>
<?php } ?>
</span>
</p>
<?php for ($i = $startPage; $i <= $endPage; $i++) { ?>
<a href="/paginate?page=<?= $i ?>">
<sapn style="color: <?= $i == $page ? "#ea4335" : '' ?>;"><?= $i ?></span>
</a>
<?php if ($i + 1 > $maxPage) {
break;
} ?>
<?php } ?>
</div>
</body>