Laravelで独自のページネーターを作成する

Laravelで独自のページネーターを作成するLaravel
Laravelで独自のページネーターを作成する

今回はLaravelのページネーターを独自に作成する方法です。
基本的に、クエリビルダやEloquentを使用してページングする方法が一般的だと思いますが、今回は取得してきた値に対して自分でページネーターを作成する方法をで行いたいと思います。
あまり、このようなシチュエーションは少ないかと思いますが、先日、この方法を使用する必要があったため、その時に調べた内容を記載します。

サンプルとして、Laravelで用意されているUsersテーブルにSeederでデータを作成しています。

Viewの作成

まずは、Viewに一覧を表示する部分を作成します。表示が確認できれば良いので見た目はちょっとおいておきます。。。

<table class="table">
    <tr>
        <th>name</th>
        <th>email</th>
    </tr>
    @foreach ($users as $user)
        <tr>
            <td>{{ $user->name }}</td>
            <td>{{ $user->email }}</td>
        </tr>
    @endforeach
</table>
{{ $users->links() }}

$users->links() の部分がページリンクを表示する部分になります。

PaginatorとLengthAwarePaginator

ページネーターは、PaginatorとLengthAwarePaginatorの2種類のクラスがあります。
ページネーターを使用する際い、paginateメソッドを呼び出す場合はLengthAwarePaginatorのインスタンスが返り、simplePaginateはPaginatorのインスタンスが返ります。
大きく違う点は、LengthAwarePaginatorは各ページのリンクが表示され、Paginatorは前後のリンクが表示されます。

呼び出しクラス表示
DB::table(‘users’)->simplePaginate(15);PaginatorPaginator
User::simplePaginate(15);PaginatorPaginator
DB::table(‘users’)->paginate(15);LengthAwarePaginatorLengthAwarePaginator
User::paginate(15);LengthAwarePaginatorLengthAwarePaginator

独自のLengthAwarePaginatorを作成する

今回は、LengthAwarePaginatorを上記のような呼び出しを行わずに作成します。

public function index(Request $request) // Requestを受け取るようにする
{
    $users = User::all();
    // LengthAwarePaginatorの作成
    $userPaginate = new LengthAwarePaginator(
        $users->forPage($request->page, 15), // 現在のページのsliceした情報(現在のページ, 1ページあたりの件数)
        $users->count(), // 総件数
        15,
        null, // 現在のページ(ページャーの色がActiveになる)
        ['path' => $request->url()] // ページャーのリンクをOptionのpathで指定
    );
    return view('home', ['users' => $userPaginate]);
}

ちょっと変数名が微妙ですが、最初のサンプルと合わせるようにしています。
forPageで一覧に表示する、sliceしたデータを指定し、総件数などをLengthAwarePaginatorに引数として渡せば作成できます。
手順的には、そんなに難しくはないかと思います。
今回はデータがコレクション型なので、forPageでsliceしていますが、配列の場合はarray_sliceなどを使ってsliceする必要があります。

Paginatorで作成する場合

Paginatorで作成する場合は、下記のようになります。

public function index(Request $request)
{
    $users = User::all();
    $userPaginate = new Paginator(
        $users,
        15,
        null,
        ['path' => $request->url()]
    );
    return view('home', ['users' => $userPaginate]);
}

第一引数には、全件のデータを渡します。また、総件数を渡す必要がありません。
そのほかは、LengthAwarePaginatorと大きく変わるところはありません。

Jsonで返す

ページネーターは、Jsonableインターフェースを実装しているので、Jsonで返すことも可能です。

$userPaginate = new LengthAwarePaginator(
    $users->forPage($request->page, 15),
    $users->count(),
    15,
    null,
    ['path' => $request->url()]
);
$userPaginate->toJson(); // Jsonに変換

もしくは、ルートやコントローラーでそのままインスタンスを返す。

$userPaginate = new LengthAwarePaginator(
    $users->forPage($request->page, 15),
    $users->count(),
    15,
    null,
    ['path' => $request->url()]
);
return $userPaginate; // Jsonで出力される

これで、クエリビルダやEloquentを使わずにページネーターを作成することが出来るかと思います。
あまり使用する機会が少ないかもしれないですが、知っておくと良いかもしれません。

タイトルとURLをコピーしました