BeginnerEngineerBlog
中の人
中の人

【php composer】ページネータライブラリを公開しました

公開: 2023-11-03 14:33
更新: 2024-04-03 00:21
90
php paginator composer
スクラッチでごくごくたまーにページネーション実装してって要望あるのでいつでも使えるようにライブラリ化してみました

こんにちは!

中の人です

言うても一回しか実装したことないんですが、フレームワークを使用していない環境でページネーション実装してくんない?っていう時があって、実装したことがあるのですが、後々のこと考えてサクッとページネーション実装できるようにライブラリ化したので、その紹介になります。
※ ちなみにmysqlの利用が前提です!今後もしかしたら普通のの配列とかpostgreとかやるかも。。多分。。

ライブラリ



いぇーい!
ついにcomposerデビューだぜ!

Packagistにプロフィールあるだけでできる人感がある笑
まぁ本当はこのサイトの画像をプロフィールに使いたかったんですけど、ちょっと画像の変更がわからなくてウルティモドラゴンさんの覆面を被った私の画像がプロフィール画像に固定されてるみたいなんであれなんですが、あれが中の人です

ちなみにパッケージ登録で参考にした記事は以下になります(ありがとうございます!)

どんなものかというと


こんな感じでpaginateのボタンを表示してくれるものです。

使い方


詳しくはREADMEにも記載していますが、簡単に紹介します

$ composer require begien/simplepaginator:~1.0

📁 root/index.php

<?php

require_once __DIR__ . '/vendor/autoload.php';// 👈 vendorの読み込み
require_once __DIR__ . '/config/config.php';// 👈 dbのコネクションとか

use Begien\Paginator; // 👈 このパッケージをインポートします

$pdo = connectDb(); // 👈 PDOインスタンス

$result_view_count = 2; // 👈 検索結果の最大表示数
$paginate_margin = 2; // 👈 ページネータで表示するボタンの余白の数

if (isset($_GET['max'])) {
    $result_view_count = (int)h($_GET['max']);
}

$sql = 'select * from users order by id asc'; // 👈 "LIMIT"以外のsqlを作成

// 👇 ページネータ取得
$paginator = new Paginator(
    $pdo,
    $sql,
    $result_view_count,
    $paginate_margin,
);

$result = $paginator->result; // 👈 検索結果
$result_count = $paginator->result_count // 👈 ヒットしたデータの数
?>

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>ページネーションテスト</title>
    </head>
    <body>
        <style>
            .paginate_button {
                margin: 0 auto;
            }
        </style>
        <div>
            <?php echo $result_count; ?>件ヒットしました。
        </div>
        <form action="" method="get" name="form">
            <input type="hidden" name="page" value=""><!-- 👈 submitするフォームにhiddenで指定してください -->
            <label for="max">表示件数</label>
            <select id="max" name="max">
                <?php for ($i = 1;5 > $i;++$i) : ?>
                    <option
                        value="<?php echo $i; ?>"
                        <?php if ((int)$result_view_count === (int)$i) :?>
                            selected="selected"
                        <?php endif; ?>
                    >
                        <?php echo $i; ?></option>
                <?php endfor; ?>
            </select>
        </form>
        <ul>
            <?php foreach ($result as $key => $user) : ?>
                <li><?php echo $user['name'] ?></li>
            <?php endforeach; ?>
        </ul>
        <?php $paginator->paginate(); ?><!-- 👈 ページネータを表示します -->
        <script>
            let max = document.getElementById('max');
            let max_form = document.querySelector('[name="form"]');
            max.addEventListener('change', function (e) {
                max_form.submit();
            });
        </script>
    </body>
</html>

これで上記の画像のような挙動になります。

オプション


大したオプションではないですが、ボタンの背景色や数字の色を変更することができます

📁 root/index.php

<?php

require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/config/config.php';

use Begien\Paginator;

$pdo = connectDb();

$result_view_count = 2;
$paginate_margin = 2;

if (isset($_GET['max'])) {
    $result_view_count = (int)h($_GET['max']);
}

$sql = 'select * from users order by id asc';

$options = Paginator::getDefaultOptions(); // 👈
$options['background_color']['default'] = 'blue'; // 👈
$options['background_color']['selected'] = 'red'; // 👈 デフォルトのオプションを取得して背景色と文字色を変更
$options['color']['default'] = 'red'; // 👈
$options['color']['selected'] = 'blue'; // 👈

$paginator = new Paginator(
    $pdo,
    $sql,
    $result_view_count,
    $paginate_margin,
    $options // 👈 セットする
);

// ~~ 省


うーんしょぼい笑

その他オプションでは、次へとか、開始、終了のボタンを表示させるかさせないかなど指定することができます


別のテンプレートを使用


前述したようにオプションはしょぼい(と言ってもこれもオプションの一部なんですが)ので、ご自身でレイアウトを作って適用することができます。

📁 root/my_paginate.php

<?php
    $is_visible_next = false;
    $is_visible_prev = false;
    $is_visible_start = false;
    $is_visible_end = false;
?>

<?php if ($this->count > 0) :?>
    <nav aria-label="Page navigation example">
        <ul class="pagination">
            <?php for ($i = 1;$this->count >= $i;++$i) : ?>
                <?php if ($this->page > 1) : ?>
                    <?php if ($this->visible_start_end && !$is_visible_start) : ?>
                        <?php $is_visible_start = true; ?>
                        <li class="page-item"><a class="page-link" data-value="<?php echo 1; ?>" href="#">Start</a></li>
                    <?php endif; ?>
                    <?php if ($this->visible_prev_next && !$is_visible_prev) : ?>
                        <?php $is_visible_prev = true; ?>
                        <li class="page-item"><a class="page-link" data-value="<?php echo $this->page - 1; ?>" href="#">Previous</a></li>
                    <?php endif; ?>
                <?php endif;?>
                <?php if (($this->page - $this->margin) > $i) : ?>
                    <?php continue; ?>
                <?php elseif (($this->page + $this->margin) < $i) : ?>
                    <?php break; ?>
                <?php endif; ?>
                <li class="page-item <?php if ((int)$this->page === (int)$i) : ?>active<?php endif; ?>"><a class="page-link" data-value="<?php echo $i; ?>" href="#"><?php echo $i; ?></a></li>
            <?php endfor; ?>
            <?php if ($this->page < $this->count) : ?>
                <?php if ($this->visible_prev_next && !$is_visible_next) : ?>
                    <?php $is_visible_next = true; ?>
                    <li class="page-item"><a class="page-link" data-value="<?php echo $this->page + 1; ?>" href="#">Next</a></li>
                <?php endif; ?>
                <?php if ($this->visible_start_end && !$is_visible_end) : ?>
                    <?php $is_visible_end = true; ?>
                    <li class="page-item"><a class="page-link" data-value="<?php echo $this->count; ?>" href="#">End</a></li>
                <?php endif; ?>
            <?php endif; ?>
        </ul>
    </nav>
<?php endif; ?>
<script>
    let buttons = document.getElementsByClassName('page-link');
    let page_input = document.querySelector('[name="<?php echo $this->page_name; ?>"]');
    for (let i = 0;buttons.length > i;++i) {
        buttons[i].addEventListener('click', function (e) {
            e.preventDefault();
            let page = e.target.dataset.value;
            let form = document.querySelector('[name="<?php echo $this->form_name; ?>"]');
            if (!form) {
                form = this.closest('form') ?? document.querySelector('form');
            }
            page_input.value = page;
            form.submit();
        });
    }
</script>

📁 root/index.php

<?php

require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/config/config.php';

use Begien\Paginator;
// ~~ 省略
$options = Paginator::getDefaultOptions(); // 👈 オプション取得
$options['paginate_path'] = __DIR__ . '/my_paginate.php'; // 👈 作ったテンプレートのパス

$paginator = new Paginator(
    $pdo,
    $sql,
    $result_view_count,
    $paginate_margin,
    $options // 👈 セットする
);

// ~~ 省



デフォルトテンプレートはREADMEに記載しているので、必要な変数などはそちらから確認してください。


終わりに


いうてもcomposerでインストールするライブラリってどうやって作るんだろ?って思ってやってみただけなんですが。。笑

今後queryBuilder的なものも利用できるようにするかもしれないししないかもしれません!

もし興味あったらぜひcomposer installして遊んでみてください。
もちろん何かのプロジェクトで利用していただいてもかまいませんし、むしろ利用していただけたら幸いです。(もっといいのあると思いますけどね!思いますけどほら、一応ね?使ってくれたら嬉しいじゃん)

もちろんgithubからコピペでもcloneでもして利用していただいても構いません

ということで

お疲れ様でした。
0
0
0
0
通信エラーが発生しました。
似たような記事