【Laravel】LengthAwarePaginatorについて解説

laravelアイキャッチ Laravel

こんにちは、かつコーチです。

LaravelでPaginationするときは、通常paginateを利用します。

しかし、その他にも特殊なものがあります。

集計したものを一覧で表示するときのpaginateは通常のもので動作するのか。。。

そんなときに使用するのが、LengthAwarePaginatorです。

LengthAwarePaginator は Laravel に標準で搭載されているクラスで、

ページネーションを実装するためのものです。

通常の paginate メソッドと似ていますが、異なる点があります。

以下で詳しく説明します。

LengthAwarePaginator とは?

LengthAwarePaginator は、ページネーションの情報に加えて、

全体のアイテム数(total)総ページ数 など、追加の情報を提供するクラスです。

特に、集計されたデータやカスタムクエリを使う場合に、

全体のデータ量を自分で管理する必要がある場面で役立ちます。

通常の paginate と LengthAwarePaginator の違い

paginate メソッド

  • 自動的にページネーションを行う: クエリに基づいて、データベースから直接データを取得し、その結果を自動的にページネーションします。
  • 全体のアイテム数の計算: paginate は自動的に全体のアイテム数をクエリで計算し、それに基づいて総ページ数や現在のページを含むページネーション情報を返します。
  • 使用シーン: 通常のクエリで、大規模なデータセットをページ単位で表示したい場合に便利です。
phpコードをコピーする$users = User::paginate(15); // 15件ずつ自動的にページネーション

LengthAwarePaginator

  • 手動でページネーション: LengthAwarePaginator を使うと、手動でアイテムの配列やコレクションにページネーションを適用することができます。クエリではなく、配列などのデータをページネーションしたい場合に使われます。
  • 全体のアイテム数を指定: 全体のアイテム数 (total) を自分で指定する必要があります。例えば、データをフィルタリングして集計した後、その集計データに対してページネーションを適用する場合に使います。
  • 使用シーン: カスタムクエリや集計結果、またはデータベースクエリ以外のソースからのデータに対してページネーションを適用したい場合に便利です。
use Illuminate\Pagination\LengthAwarePaginator;

// 集計データを手動でページネーション
$attendanceData = [/* 集計データの配列 */];
$currentPage = request()->get('page', 1);
$perPage = 20;
$offset = ($currentPage - 1) * $perPage;

// 現在のページに表示するデータ
$items = array_slice($attendanceData, $offset, $perPage);

// 手動で全体のデータ数を指定
$paginatedData = new LengthAwarePaginator($items, count($attendanceData), $perPage, $currentPage, [
    'path' => request()->url(),
    'query' => request()->query(),
]);

このように、LengthAwarePaginator を使用すると、全体のデータ数や総ページ数、

現在のページ情報を含むページネーションを手動で制御できます。

LengthAwarePaginator のプロパティとメソッド

LengthAwarePaginator は以下の情報を提供することができます。

  • total: 全体のアイテム数。
  • currentPage: 現在のページ番号。
  • lastPage: 総ページ数。
  • perPage: 1ページあたりのアイテム数。
  • nextPageUrl: 次のページのURL。
  • previousPageUrl: 前のページのURL。

これにより、カスタムなデータでも詳細なページネーションを実装できます。

特殊なページネータ

Laravel には他にもいくつかのページネーションの方法があります。

SimplePaginator:

  • 通常の paginate と似ていますが、全体のアイテム数や総ページ数を表示しないシンプルなページネーションです。

  • total の計算を省略するため、非常に大きなデータセットを扱うときにパフォーマンスを向上させたい場合に役立ちます。

    $users = User::simplePaginate(15); // ページ数などを計算せず、シンプルに次・前のページへ移動

    CursorPaginator:

    • ページ番号を使わず、カーソルベースのページネーションを行います。

    • 無限スクロールなどの用途に便利です。大規模なデータセットで、ページ数を計算せずに次のデータを効率的に取得したい場合に使います。

      $users = User::cursorPaginate(15); // カーソルを使ったページネーション

      LengthAwarePaginator と集計データ

      今回のように、集計結果をまとめたデータに対してページネーションを行いたい場合には、

      LengthAwarePaginator が非常に有効です。

      データベースクエリではなく、手動で集計したデータや配列に対してページネーションを適用できます。

      // 集計結果が入っている配列
      $attendanceData = [
          ['lesson_name' => 'Math', 'course_name' => 'Basic', 'attendance_count' => 10, 'absence_count' => 2],
          // 他のデータ...
      ];
      
      // ページネーションのための設定
      $perPage = 20;
      $currentPage = request()->get('page', 1);
      $offset = ($currentPage - 1) * $perPage;
      
      // 配列をページ単位に分割
      $items = array_slice($attendanceData, $offset, $perPage);
      
      // 全体数を手動で指定
      $paginatedData = new LengthAwarePaginator($items, count($attendanceData), $perPage, $currentPage, [
          'path' => request()->url(),
          'query' => request()->query(),
      ]);
      
      // これをビューに渡して、ページネーションリンクなどを表示

      結論

      • LengthAwarePaginator は、手動でページネーションを制御したい場合に適しており、特にクエリの結果ではなく、配列や集計結果などに対して使用することができます。
      • 通常の paginate はデータベースクエリに基づいて自動でページネーションを行うのに対して、LengthAwarePaginator はページネーションのロジックを手動で設定し、カスタムなデータに対応します。
      • simplePaginatecursorPaginate など、他のページネーション方法もあり、用途によって使い分けることが可能です。

      集計データにも LengthAwarePaginator を使ってページネーションを適用することで、

      柔軟かつ効率的にデータを表示できるようになります。

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