ホームページ > バックエンド開発 > PHPチュートリアル > Laravelのページネーションのガイド

Laravelのページネーションのガイド

Johnathan Smith
リリース: 2025-03-06 02:04:09
オリジナル
633 人が閲覧しました

ページネーションは、Webアプリケーションの一般的な機能です。私が今まで取り組んだほぼすべてのLaravelアプリケーションには、何らかの形のページネーションが実装されています。

しかし、ページネーションとは何ですか?なぜそれを使用するのですか? Laravelアプリケーションにページネーションを実装するにはどうすればよいですか?そして、どのページネーション方法を使用するかをどのように決定しますか? この記事では、これらの質問に答え、ブレードビューとAPIエンドポイントの両方でLaravelでページネーションを使用する方法を探ります。この記事の終わりまでに、あなたはあなた自身のプロジェクトでページネーションの使用を開始するのに十分自信を感じるべきです。

#パジネーションとは?

ページネーションは、大きなデータセットを小さなチャンク(またはページ)に分割するために使用される手法です。これにより、可能なすべての値を一度にではなく、データのサブセットを表示できます。 たとえば、

アプリケーション内のすべてのユーザーの名前を出力するページがあると想像してください。何千人ものユーザーがいる場合、1つのページにすべてを表示することは実用的ではありません。代わりに、ページネーションを使用して、各ページにユーザーのサブセット(一度に10人のユーザーなど)を表示し、ユーザーがページ間でナビゲートしてより多くのユーザーを表示できるようにすることができます(次の10人)。

ページネーションを使用することで、

アプリケーションのパフォーマンスを改善します - 一度にデータのサブセットを小さなサブセットに取得しているため、データベースから取得するデータが少なくなり、プロセス/変換があります。

ユーザーエクスペリエンスの改善 - ユーザーは、一度にデータの小さなサブセットにのみ関心がある可能性があります(通常、最初の数ページ、特にフィルターと検索用語が使用されている場合)。ページネーションを使用することにより、ユーザーが興味のないデータの表示を避けることができます。

ページの読み込み時間の改善 - 一度にデータのサブセットを取得するだけで、ページにロードする必要があるデータの量を減らすことができます。

ページネーションは、通常、2つの異なるタイプに分割できます。
  • オフセットベースのページネーション - これは、特にユーザーインターフェイス(UI)でWebアプリで出会う可能性が高い最も一般的なタイプのページネーションです。 「オフセット」と「制限」に基づいて、データベースからデータのサブセットを取得することが含まれます。たとえば、20番目のレコードから10のレコードを取得して、データの3番目のページを取得できます。
  • カーソルベースのページネーション - このタイプのページネーションでは、「カーソル」に基づいてデータのサブセットを取得することが含まれます。カーソルは通常、データベースのレコードの一意の識別子です。たとえば、20のIDでレコードから始まる次の10のレコードを取得できます。
  • laravelは、アプリケーションで雄弁なクエリをページングするための3つの異なる方法を提供します。
    • paginate - オフセットベースのページネーションを使用し、データセット内のレコードの総数を取得します。
    • - オフセットベースのページネーションを使用しますが、データセットのレコードの総数は取得しません。 simplePaginate
    • - カーソルベースのページネーションを使用し、データセット内のレコードの総数を取得しません。
    • cursorPaginateこれらの各メソッドをより詳細に見てみましょう。
    #USENING

    メソッド

    この方法では、オフセットと制限に基づいてデータベースからデータのサブセットを取得できます(基礎となるSQLクエリを見ると、これらを後で見てみましょう)。 paginate

    メソッドを使用できます

    上記のコードを実行すると、paginate

    、通常は

    オブジェクトのインスタンスになります。このPaginatorインスタンスには、アプリケーションにPaginatedデータを表示するために必要なすべての情報が含まれています。 paginate

    メソッドは、URLの
    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    
    $users = User::query()->paginate();
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    クエリパラメーターに基づいて、要求されたページ番号を自動的に決定できます。たとえば、

    にアクセスした場合、$usersメソッドはデータの2番目のページを取得します。 IlluminateContractsPaginationLengthAwarePaginatorデフォルトでは、Laravelのすべてのページネーション方法は、デフォルトで一度に15のレコードを取得するようになります。ただし、これは別の値に変更できます(後でこれを行う方法をご覧ください)。 ブレードビューを使用したIlluminatePaginationLengthAwarePaginator #USING

    paginateブレードビューでデータをレンダリングするときにpageメソッドの使用方法を見てみましょう。 https://my-app.com/users?page=2データベースからユーザーを塗装した形式で取得し、ビューに渡す単純なルートがあると想像してください:paginate

    私たちの

    ファイルは次のように見えるかもしれません:

    paginate

    結果のページは次のようになります:

    paginate

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('users', function () {
        $users = User::query()->paginate();
    
        return view('users.index', [
            'users' => $users,
        ]);
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ブレードビューで何が起こっているのかを分解しましょう:

    • $usersフィールド(IlluminatePaginationLengthAwarePaginatorオブジェクト)に存在する各ユーザーをループし、名前を出力します。
    • オブジェクト上のlinksメソッドを呼び出しています。これは、ページネーションリンク(「前」、「次」、ページ番号など)を表示するHTMLを返す非常に便利な方法です。これは、ページネーションリンクを自分で作成することを心配する必要がないことを意味し、Laravelはあなたのためにそのすべてを処理します。 $users また、この方法では、ページネーションデータの概要が得られていることがわかります。合計50のレコードのうち、16番目から30番目のレコードを表示していることがわかります。また、私たちは2ページ目にあり、合計4ページがあることもわかります。
    メソッドは、Tailwind CSSを使用してスタイルのHTMLを返すことに注意することが重要です。 Tailwind以外のものを使用したい場合、またはページネーションリンクを自分でスタイリングしたい場合は、ページネーションビューのカスタマイズに関するドキュメントを確認できます。 API Endpoints

    inpaginate#USING

    ブレードビューでlinksメソッドを使用するだけでなく、APIエンドポイントでも使用することもできます。 Laravelは、このプロセスをパジネートデータをJSONに自動的に変換することで簡単にします。 たとえば、

    エンドポイントを構築できます(次のルートをpaginateファイルに追加することで)JSON形式でパジネートされたユーザーを返します。

    エンドポイントにアクセスすると、次のようなJSON応答が返されます(簡潔にするためにpaginateフィールドに3つのレコードに限定されています):

    /api/users JSON応答を分解しましょう:routes/api.php

    • current_page - 現在のページ。この場合、最初のページに載っています
    • - 返されている実際のデータ自体。この場合、最初の15人のユーザーが含まれています(簡潔にするために3に短縮されました)。 data
    • - データの最初のページへのURL。
    • first_page_url
    • - 返されるデータの開始記録番号。この場合、それは最初のレコードです。私たちが2番目のページにいた場合、これは16になります。
    • from - データのページの総数。この場合、4ページがあります。
    • last_page - データの最後のページへのURL。
    • last_page_url - 異なるデータのページへのリンクの配列。これには、「以前の」および「次の」リンク、およびページ番号が含まれます。
    • - データの次のページのURL。links
    • - エンドポイントのベースURL。next_page_url
    • - ページごとに返されるレコードの数。この場合、それは15です path
    • - データの前のページのURL。この場合、私たちが最初のページにいるので、それは
    • です。 2番目のページにいた場合、これは最初のページのURLになります。per_page
    • - 返されるデータの終了レコード番号。この場合、それは15番目のレコードです。 2ページ目にいた場合、これは30になります。 prev_page_urlnull - データセット内のレコードの総数。この場合、50のレコードがあります。
    • to#基礎となるSQLクエリ
    • Laravelで
    • メソッドを使用すると、2つのSQLクエリが実行されています。 total
    • 最初のクエリは、データセット内のレコードの総数を取得します。これは、ページの総数やレコードの総数などの情報を決定するために使用されます。 2番目のクエリは、オフセットと制限値に基づいてデータのサブセットを取得します。たとえば、私たちが処理して返すようにユーザーをフェッチしている可能性があります。

    したがって、ユーザーの最初のページ(ページごとに15人のユーザーがいる)を取得したい場合、次のSQLクエリが実行されます。

    およびpaginate

    2番目のクエリでは、
      値が15に設定されていることがわかります。これはページごとに返されるレコードの数です。
    • 値は次のように計算されます:
    したがって、ユーザーの3番目のページを取得したい場合、

    値は次のように計算されます。

    したがって、
    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    
    $users = User::query()->paginate();
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    値は30になり、31番目から45番目のレコードを取得します。 3番目のページのクエリは次のようになります:

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('users', function () {
        $users = User::query()->paginate();
    
        return view('users.index', [
            'users' => $users,
        ]);
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    およびlimit

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    
    $users = User::query()->paginate();
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    #USENINGsimplePaginateメソッド

    simplePaginateメソッドはpaginateメソッドに非常に似ていますが、1つの重要な違いがあります。 simplePaginateメソッドは、データセット内のレコードの総数を取得しません。

    今後見たように、メソッドを使用すると、データセットで利用可能なレコードとページの総数に関する情報も取得されます。その後、この情報を使用して、UIまたはAPI応答のページの総数を表示できます。

    しかし、これらの詳細をユーザー(またはAPIを消費する開発者)に表示するつもりがない場合は、paginateメソッドを使用して、不要なデータベースクエリ(レコードの総数をカウント)を回避できます。

    メソッドと同じ方法で使用できます。 simplePaginate 上記のコードを実行すると、

    、通常はsimplePaginateオブジェクトのインスタンスになります。 paginate メソッドによって返されるオブジェクトとは異なり、<!-- Syntax highlighted by torchlight.dev -->use App\Models\User; use Illuminate\Support\Facades\Route; Route::get('users', function () { $users = User::query()->paginate(); return view('users.index', [ 'users' => $users, ]); }); オブジェクトはデータセット内のレコードの総数に関する情報を含めておらず、ページまたは合計レコードがいくつあるかわかりません。データの現在のページと、フェッチするレコードがもっとあるかどうかについて知っています。 ブレードビューを使用した

    #USING $usersIlluminateContractsPaginationPaginator IlluminatePaginationPaginatorブレードビューで

    メソッドを使用する方法を見てみましょう。以前と同じルートがあると仮定しますが、今回は

    メソッドを使用しています。 IlluminatePaginationLengthAwarePaginator paginate以前と同じようにブレードビューを構築します:IlluminatePaginationPaginator

    結果のページは次のようになります:simplePaginate

    simplePaginate simplePaginate この例でわかるように、

    メソッドを使用したときに見た出力と
    <!-- Syntax highlighted by torchlight.dev --><html>
    <head>
        <title>Paginate</title>
        <script src="https://cdn.tailwindcss.com"></script>
    </head>
    
    <body>
        <div class="max-w-5xl mx-auto py-8">
            <h1 class="text-5xl">Paginate</h1>
    
            <ul class="py-4">
                @foreach ($users as $user)
                    <li class="py-1 border-b">{{ $user->name }}</li>
                @endforeach
            </ul>
    
            {{ $users->links() }}
        </div>
    </body>
    </html>
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    の出力は異なります。

    メソッドはレコードの総数を取得しないため、ページまたはレコードの総数のコンテキストはありません。次のページがあるかどうかのみです。したがって、ページネーションリンクに「前」と「次の」リンクのみが表示されます。 API Endpoints

    in
    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('paginate', function () {
        return User::query()->paginate();
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    #USING

    APIエンドポイントで

    メソッドを使用することもできます。 Laravelは、あなたのためにPaginatedデータをJSONに自動的に変換します。 JSON形式でパジネートされたユーザーを返すエンドポイントを構築しましょう:

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    
    $users = User::query()->paginate();
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    このルートを訪れたとき、次のようなJSON応答を取得します(dataフィールドは、簡潔にするために3つのレコードに限定されています):

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('users', function () {
        $users = User::query()->paginate();
    
        return view('users.index', [
            'users' => $users,
        ]);
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    ご覧のとおり、JSON応答は、paginateメソッドを使用するときに得た応答と非常に似ています。重要な違いは、応答にlast_pagelast_page_urllinks、またはtotalフィールドがないことです。

    #基礎となるSQLクエリ

    メソッドを使用したときに実行される基礎となるSQLクエリを見てみましょう。 simplePaginate

    メソッドは、データベースからデータのサブセットを取得するために

    値とsimplePaginate値に依存しています。ただし、データセット内のレコードの総数を取得するためのクエリを実行しません。 limitoffset値は、以前と同じように計算されます:

    ただし、offset

    値は、
    <!-- Syntax highlighted by torchlight.dev --><html>
    <head>
        <title>Paginate</title>
        <script src="https://cdn.tailwindcss.com"></script>
    </head>
    
    <body>
        <div class="max-w-5xl mx-auto py-8">
            <h1 class="text-5xl">Paginate</h1>
    
            <ul class="py-4">
                @foreach ($users as $user)
                    <li class="py-1 border-b">{{ $user->name }}</li>
                @endforeach
            </ul>
    
            {{ $users->links() }}
        </div>
    </body>
    </html>
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    メソッドとはわずかに異なる方法で計算されます。次のように計算されています

    これは、limitメソッドがpaginate値よりも1つのレコードを取得する必要があるためです。たとえば、ページごとに15のレコードを取得しているとしましょう。

    値は16になります。したがって、16のレコードが返された場合、Fetchが利用できるデータの少なくとも1つのページがあることがわかります。 16未満のレコードが返された場合、データの最後のページに載っていることがわかります。
    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('paginate', function () {
        return User::query()->paginate();
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    したがって、ユーザーの最初のページ(ページごとに15人のユーザーがいる)を取得したい場合、次のSQLクエリが実行されます。

    simplePaginate 2番目のページのクエリは次のようになります:perPage limit

    #USENING

    メソッド

    <!-- Syntax highlighted by torchlight.dev -->{
      "current_page": 1,
      "data": [
        {
          "id": 1,
          "name": "Andy Runolfsson",
          "email": "teresa.wiegand@example.net",
          "email_verified_at": "2024-10-15T23:19:28.000000Z",
          "created_at": "2024-10-15T23:19:29.000000Z",
          "updated_at": "2024-10-15T23:19:29.000000Z"
        },
        {
          "id": 2,
          "name": "Rafael Cummings",
          "email": "odessa54@example.org",
          "email_verified_at": "2024-10-15T23:19:28.000000Z",
          "created_at": "2024-10-15T23:19:29.000000Z",
          "updated_at": "2024-10-15T23:19:29.000000Z"
        },
        {
          "id": 3,
          "name": "Reynold Lindgren",
          "email": "juwan.johns@example.net",
          "email_verified_at": "2024-10-15T23:19:28.000000Z",
          "created_at": "2024-10-15T23:19:29.000000Z",
          "updated_at": "2024-10-15T23:19:29.000000Z"
        }
      ],
      "first_page_url": "http://example.com/users?page=1",
      "from": 1,
      "last_page": 4,
      "last_page_url": "http://example.com/users?page=4",
      "links": [
        {
          "url": null,
          "label": "&laquo; Previous",
          "active": false
        },
        {
          "url": "http://example.com/users?page=1",
          "label": "1",
          "active": true
        },
        {
          "url": "http://example.com/users?page=2",
          "label": "2",
          "active": false
        },
        {
          "url": "http://example.com/users?page=3",
          "label": "3",
          "active": false
        },
        {
          "url": "http://example.com/users?page=4",
          "label": "4",
          "active": false
        },
        {
          "url": "http://example.com/users?page=5",
          "label": "5",
          "active": false
        },
        {
          "url": "http://example.com/users?page=2",
          "label": "Next &raquo;",
          "active": false
        }
      ],
      "next_page_url": "http://example.com/users?page=2",
      "path": "http://example.com/users",
      "per_page": 15,
      "prev_page_url": null,
      "to": 15,
      "total": 50
    }
    
    ログイン後にコピー
    ログイン後にコピー
    これまでのところ、両方ともオフセットベースのページネーションを使用する

    および

    メソッドを調べました。次に、カーソルベースのページネーションを使用する
    <!-- Syntax highlighted by torchlight.dev -->select count(*) as aggregate from `users`
    
    ログイン後にコピー
    メソッドをご覧ください。

    ヘッドアップとして、カーソルベースのページネーションは、初めて出会ったときに少し混乱するように見えるかもしれません。だから、あなたがすぐにそれを手に入れていなくても心配しないでください。うまくいけば、この記事の終わりまでに、あなたがそれがどのように機能するかをよりよく理解できるでしょう。また、この記事の最後に、カーソルベースのページネーションをより詳細に説明する素晴らしいビデオも残します。 オフセットベースのページネーションを使用すると、cursorPaginateおよび

    値を使用して、データベースからデータのサブセットを取得します。したがって、「最初の10のレコードをスキップして、次の10のレコードを取得する」と言うことができます。これは簡単に理解しやすく、実装が簡単です。一方、カーソルページネーションを使用すると、以前の/次のレコードセットを取得するための出発点としてカーソル(通常、データベースの特定のレコードの一意の識別子)を使用します。たとえば、

    最初の15人のユーザーをフェッチするためのクエリを作成したとします。 15番目のユーザーのIDは20であると仮定します。次の15人のユーザーを取得する場合、15番目のユーザー(20)のIDをカーソルとして使用します。 「20を超えるIDを持つ次の15人のユーザーを取得する」と言います。

    「トークン」、「キー」、「次」、「前」などと呼ばれるカーソルが表示される場合があります。それらは基本的にデータベース内の特定のレコードへの参照です。基礎となるSQLクエリを見てみると、このセクションの後半のカーソルの構造を見てください。

    laravelを使用すると、

    メソッドを使用してカーソルベースのページネーションを簡単に使用できます。 cursorPaginate 上記のコードを実行すると、

    フィールドが
    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    
    $users = User::query()->paginate();
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    、通常は

    オブジェクトのインスタンスになります。このPaginatorインスタンスには、アプリケーションにPaginatedデータを表示するために必要なすべての情報が含まれています。 $users IlluminateContractsPaginationCursorPaginatorメソッドと同様に、IlluminatePaginationCursorPaginatorメソッドはデータセット内のレコードの総数を取得しません。データの現在のページとフェッチするレコードが増えるかどうかについてのみ知っているので、ページまたはレコードの総数をすぐに認識していません。 ブレードビューを使用した

    #USING

    simplePaginate cursorPaginateブレードビューでデータをレンダリングするときに

    メソッドを使用する方法を見てみましょう。以前の例と同様に、データベースからユーザーを塗装した形式で取得し、ビューに渡す簡単なルートがあると仮定します。

    cursorPaginateブレードビューは次のように見えるかもしれません:

    cursorPaginateこれにより、次のようなページが出力されます

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('users', function () {
        $users = User::query()->paginate();
    
        return view('users.index', [
            'users' => $users,
        ]);
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    <!-- Syntax highlighted by torchlight.dev --><html>
    <head>
        <title>Paginate</title>
        <script src="https://cdn.tailwindcss.com"></script>
    </head>
    
    <body>
        <div class="max-w-5xl mx-auto py-8">
            <h1 class="text-5xl">Paginate</h1>
    
            <ul class="py-4">
                @foreach ($users as $user)
                    <li class="py-1 border-b">{{ $user->name }}</li>
                @endforeach
            </ul>
    
            {{ $users->links() }}
        </div>
    </body>
    </html>
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    メソッドはデータセット内のレコードの総数を取得しないため、

    の出力はメソッドを使用する際に見た出力に似ています。ページネーションリンクに「前」と「次の」リンクのみが表示されます。 API Endpoints in

    #USING

    cursorPaginate laravelでは、APIエンドポイントで$users->links()メソッドを使用することもでき、パジネートされたデータをJSONに自動的に変換します。 simplePaginateJSON形式でパジネートされたユーザーを返す

    エンドポイントを構築しましょう:

    cursorPaginate

    このルートを訪れたとき、次のようなJSON応答を取得します(

    フィールドは、簡潔にするために3つのレコードに限定されています):cursorPaginate

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    
    $users = User::query()->paginate();
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    ご覧のとおり、JSON応答は、私たちが見た以前の応答と似ていますが、いくつかの小さな違いがあります。レコードの総数を取得していないため、応答にはlast_pagelast_page_urllinks、またはtotalフィールドはありません。また、fromtoのフィールドもないことに気づいたかもしれません。 代わりに、次のデータの次のページと以前のページのカーソルを含む

    および

    フィールドがあります。私たちは最初のページにいるので、next_cursorprev_cursorのフィールドは両方ともprev_cursorです。ただし、prev_page_urlおよびnullフィールドは設定されています next_cursornext_page_urlフィールドは、データの次のページのカーソルを含むベース64エンコード文字列です。

    フィールドをデコードすると、このようなものが得られます(読みやすさのために美化されます):

    next_cursor next_cursorカーソルには、2つの個別の情報が含まれています。

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('users', function () {
        $users = User::query()->paginate();
    
        return view('users.index', [
            'users' => $users,
        ]);
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    - データセットで取得した最後のレコードのID。
    • users.id - カーソルが次のアイテムまたは以前のセットを指しているかどうかを示すブール値。値が
    • の場合、カーソルを使用して、
    • 値より大きいIDを使用して次のレコードセットを取得する必要があります。値が_pointsToNextItemsの場合、それはカーソルを使用して、true値より少ないIDで以前のレコードセットを取得する必要があることを意味します。 users.id falseデータの2番目のページがどのように見えるかを見てみましょう(繰り返しますが、Brevityのために3つのレコードに短縮されます):users.id

    のフィールドが設定され、
    <!-- Syntax highlighted by torchlight.dev --><html>
    <head>
        <title>Paginate</title>
        <script src="https://cdn.tailwindcss.com"></script>
    </head>
    
    <body>
        <div class="max-w-5xl mx-auto py-8">
            <h1 class="text-5xl">Paginate</h1>
    
            <ul class="py-4">
                @foreach ($users as $user)
                    <li class="py-1 border-b">{{ $user->name }}</li>
                @endforeach
            </ul>
    
            {{ $users->links() }}
        </div>
    </body>
    </html>
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    および

    フィールドがデータの次のページのカーソルで更新されていることがわかります。 prev_cursor#基礎となるSQLクエリprev_page_url next_cursorフードの下でカーソルページネーションがどのように機能するかをよりよく理解するために、next_page_urlメソッドを使用したときに実行される基礎となるSQLクエリを見てみましょう。

    データの最初のページ(15のレコードを含む)では、次のSQLクエリが実行されます。

    テーブルから最初の16のレコードを取得し、cursorPaginate列で昇順で注文することがわかります。

    メソッドと同様に、フェッチするレコードがもっとあるかどうかを判断したいので、16行を取得します。

    次のカーソルを使用してアイテムの次のページに移動することを想像しましょう。

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('paginate', function () {
        return User::query()->paginate();
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    このカーソルがデコードされると、次のJSONオブジェクトが取得されます。

    usersLaravelは次のSQLクエリを実行して、次のレコードセットを取得します。

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    
    $users = User::query()->paginate();
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    ご覧のとおり、15を超えるusersテーブルから次の16のレコードを取得しています(15が前のページの最後のIDであったため)id

    2ページの最初のユーザーのIDが16であると仮定しましょう。2番目のページのデータの最初のページに戻ると、次のカーソルを使用します。

    これがデコードされると、次のJSONオブジェクトが取得されます。
    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('users', function () {
        $users = User::query()->paginate();
    
        return view('users.index', [
            'users' => $users,
        ]);
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    結果の次のページに移動すると、最後のレコードが取得されたときにカーソルとして使用されます。結果の前のページに戻ると、最初のレコードフェッチがカーソルとして使用されます。このため、カーソルで

    値が16に設定されていることがわかります。また、前のアイテムのセットに戻るため、
    <!-- Syntax highlighted by torchlight.dev --><html>
    <head>
        <title>Paginate</title>
        <script src="https://cdn.tailwindcss.com"></script>
    </head>
    
    <body>
        <div class="max-w-5xl mx-auto py-8">
            <h1 class="text-5xl">Paginate</h1>
    
            <ul class="py-4">
                @foreach ($users as $user)
                    <li class="py-1 border-b">{{ $user->name }}</li>
                @endforeach
            </ul>
    
            {{ $users->links() }}
        </div>
    </body>
    </html>
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    値が

    に設定されていることもわかります。 users.idその結果、以前のレコードセットを取得するために、次のSQLクエリが実行されます。 _pointsToNextItems falseご覧のとおり、

    制約は16未満(16が2ページの最初のIDであるため)のレコードをチェックしており、結果は下降順序で順序付けられています。

    ##Using APIリソースをページネーション

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('paginate', function () {
        return User::query()->paginate();
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    これまでのところ、APIの例では、ページ化されたデータをコントローラーから直接返しました。ただし、実際のアプリケーションでは、データをユーザーに返す前に処理する可能性があります。これは、フィールドの追加または削除、データ型の変換、またはデータを完全に異なる形式に変換することから、何でもかまいません。このため、APIリソースは、データを返す前に一貫して変換する方法を提供するため、おそらく使用することをお勧めします。

    Laravelを使用すると、PaginationとともにAPIリソースを使用できます。これを行う方法の例を見てみましょう。where id返品する前にユーザーデータを変換するAPIリソースクラスを作成したと想像してください。このようなものになるかもしれません:

    メソッドでは、このリソースを介してユーザーを処理するときはいつでも、

    、および

    フィールドを返したいと定義しています。

    AppHttpResourcesUserResource

    を使用して、パジネートされたユーザーを返すシンプルな
    <!-- Syntax highlighted by torchlight.dev -->{
      "current_page": 1,
      "data": [
        {
          "id": 1,
          "name": "Andy Runolfsson",
          "email": "teresa.wiegand@example.net",
          "email_verified_at": "2024-10-15T23:19:28.000000Z",
          "created_at": "2024-10-15T23:19:29.000000Z",
          "updated_at": "2024-10-15T23:19:29.000000Z"
        },
        {
          "id": 2,
          "name": "Rafael Cummings",
          "email": "odessa54@example.org",
          "email_verified_at": "2024-10-15T23:19:28.000000Z",
          "created_at": "2024-10-15T23:19:29.000000Z",
          "updated_at": "2024-10-15T23:19:29.000000Z"
        },
        {
          "id": 3,
          "name": "Reynold Lindgren",
          "email": "juwan.johns@example.net",
          "email_verified_at": "2024-10-15T23:19:28.000000Z",
          "created_at": "2024-10-15T23:19:29.000000Z",
          "updated_at": "2024-10-15T23:19:29.000000Z"
        }
      ],
      "first_page_url": "http://example.com/users?page=1",
      "from": 1,
      "last_page": 4,
      "last_page_url": "http://example.com/users?page=4",
      "links": [
        {
          "url": null,
          "label": "&laquo; Previous",
          "active": false
        },
        {
          "url": "http://example.com/users?page=1",
          "label": "1",
          "active": true
        },
        {
          "url": "http://example.com/users?page=2",
          "label": "2",
          "active": false
        },
        {
          "url": "http://example.com/users?page=3",
          "label": "3",
          "active": false
        },
        {
          "url": "http://example.com/users?page=4",
          "label": "4",
          "active": false
        },
        {
          "url": "http://example.com/users?page=5",
          "label": "5",
          "active": false
        },
        {
          "url": "http://example.com/users?page=2",
          "label": "Next &raquo;",
          "active": false
        }
      ],
      "next_page_url": "http://example.com/users?page=2",
      "path": "http://example.com/users",
      "per_page": 15,
      "prev_page_url": null,
      "to": 15,
      "total": 50
    }
    
    ログイン後にコピー
    ログイン後にコピー
    APIエンドポイントを

    ファイルに作成しましょう。 toArray 上記のコードでは、データベースからユーザーの単一ページ(15人のユーザーを含む最初のページだと仮定します)を取得しています。次に、フィールド(これはidのインスタンスになります)をnameメソッドに渡します。このメソッドは、ユーザーに返す前にemailを使用して塗装されたデータを変換します。

    /api/usersエンドポイントを押すと、次のようなJSON応答が表示されます(dataフィールドは、簡潔にするために3つのレコードに限定されています):

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    
    $users = User::query()->paginate();
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    上記のJSONで見ることができるように、Laravelは、私たちがページングされたデータセットを使用して作業していることを検出し、以前と同様の形式で塗装されたデータを返します。ただし、今回は、

    フィールドのユーザーには、APIリソースクラスで指定されたdataid、およびnameフィールドのみが含まれています。他のフィールド(emailcurrent_pagefromlast_pagelinkspathper_page、、to)は、それらがパジネートされたデータの一部であるため、まだ返されますが、それらはtotalフィールド内に配置されています。また、データの異なるページへのmetalinksfirst、およびlastリンクを含むprevフィールドもあります。next

    #1ページごとの値を変える

    ページングされたデータを使用してビューを構築する場合、ユーザーがページごとに表示されるレコードの数を変更できるようにする場合があります。これは、ドロップダウンまたは数値入力フィールドを介して行われる可能性があります。

    laravelを使用すると、

    、およびperPageメソッドにパラメーターを渡すことにより、ページごとに表示されるレコードの数を簡単に変更できます。このパラメーターを使用すると、ページごとに表示するレコードの数を指定できます。 simplePaginate paginateクエリパラメーターを読み取る方法の簡単な例を見てみましょう。これを使用して、ページごとに取得されるレコードの数を変更します。 cursorPaginate

    上記の例では、クエリパラメーターの値をつかんでいます。値が提供されていない場合、デフォルトは10になります。その後、その値を

    メソッドのper_pageパラメーターに渡します。

    これらの異なるURLにアクセスできました:
    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    use Illuminate\Support\Facades\Route;
    
    Route::get('users', function () {
        $users = User::query()->paginate();
    
        return view('users.index', [
            'users' => $users,
        ]);
    });
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー

    per_pageperPage - ページごとに10のレコードを持つユーザーの最初のページを表示します。 paginate

    - ページごとに5つのレコードを持つユーザーの最初のページを表示します。

    - ページごとに5つのレコードを持つユーザーの2番目のページを表示します。
      など...
    • https://my-app.com/users
    • #どのページネーション方法を使用するかを決定する方法
    • https://my-app.com/users?per_page=5さまざまな種類のページネーションとLaravelでそれらを使用する方法を調べたので、アプリケーションで使用するアプローチを決定する方法について説明します。
    • #ページ番号またはレコードの総数が必要ですか?
    • https://my-app.com/users?per_page=5&page=2表示されるレコードまたはページの総数を必要とするUIまたはAPIのエンドポイントを構築する場合、
    • メソッドはおそらく賢明な選択です。

      これらのいずれかを必要としない場合、simplePaginateまたはcursorPaginateは、レコードの総数をカウントするために不必要なクエリを実行しないため、より効率的になります。

      #特定のページにジャンプする必要がありますか?

      データの特定のページにジャンプできる必要がある場合は、オフセットベースのページネーションがより適切です。カーソルページネーションはステートフルであるため、次の場所を知るために前のページに依存しています。したがって、特定のページにジャンプするのは簡単ではありません。

      オフセットページネーションを使用する場合、通常、リクエストのページ番号(クエリパラメーターとして)を渡して、前のページのコンテキストを持たずにそのページにジャンプすることができます。

      #データセットはどれくらい大きいですか?

      データベースが

      値を処理する方法により、ページ番号が増加するにつれてオフセットベースのページネーションは効率が低下します。これは、オフセットを使用している場合、データベースはすべてのレコードをオフセット値までスキャンする必要があるためです。それらはただ捨てられており、クエリの結果に返されません。 offsetこれをより詳細に説明する素晴らしい記事を次に示します:https://use-the-index-luke.com/no-offset。

      データベース内のデータの総量が増加し、ページ数が増加すると、オフセットベースのページネーションが効率が低下する可能性があります。これらの場合、以前のレコードが読まれていないため、特にカーソルフィールドがインデックス化されている場合、カーソルベースのページネーションはよりパフォーマンスがあります。このため、大きなデータセットに対してページネーションを使用する場合は、オフセットページネーションよりもカーソルページネーションを選択することをお勧めします。

      #データセットは頻繁に変更される可能性がありますか?

      オフセットベースのページネーションは、基礎となるデータセットがリクエスト間で変更された場合、問題に苦しむ可能性があります。

      例を見てみましょう。

      データベースに次の10人のユーザーがいるとしましょう。

      ユーザー1

      ユーザー2

        ユーザー3
      • ユーザー4
      • ユーザー5
      • ユーザー6
      • ユーザー7
      • ユーザー8
      • ユーザー9
      • ユーザー10
      • 最初のページ(5人のユーザーを含む)を取得し、次のユーザーを取得するリクエストを行います。
      • ユーザー1
      ユーザー2

      ユーザー3
      • ユーザー4
      • ユーザー5
      • 2ページに移動すると、ユーザーが6〜10になると予想されます。ただし、ページ2をロードする前に(1ページを表示している間)、ユーザー1がデータベースから削除されることを想像してみましょう。ページサイズは5であるため、次のページを取得するクエリは次のようになります。
      • これは、最初の5つのレコードをスキップして次の5を取得することを意味します。
      • これにより、次のユーザーが含まれる2ページになります。
      • ユーザー7

      ユーザー8

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    
    $users = User::query()->paginate();
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ユーザー9

    ユーザー10

      ご覧のとおり、ユーザー6はリストから欠落しています。これは、ユーザー6がテーブルの5番目のレコードであるため、実際には最初のページにあるためです。

      カーソルベースのページネーションにはこの問題はありません。レコードをスキップしていないため、カーソルに基づいて次のレコードセットを取得するだけです。上記の例でカーソルベースのページネーションを使用したと想像しましょう。 2ページのカーソルは、最初のページの最後のレコードであったため、ユーザー5のID(これは5)です。したがって、2ページ目のクエリは次のようになるかもしれません:

    <!-- Syntax highlighted by torchlight.dev -->use App\Models\User;
    
    $users = User::query()->paginate();
    
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    ログイン後にコピー
    上記のクエリを実行すると、予想通りにユーザーが6〜10を返します。

    これは、基礎となるデータが読み取られている間に変更、追加、または削除されたときに、オフセットベースのページネーションがどのように問題になるかを強調することを願っています。予測の低下になり、予期しない結果につながる可能性があります。

    #APIを構築しますか?

    アプリケーションで単一のタイプのページネーションを使用することに固定されていないことを覚えておくことが重要です。一部の場所では、オフセットのページネーションがより適切である場合(おそらくUIの目的で)、他の場所では、カーソルページネーションがより効率的になる場合があります(大きなデータセットを操作する場合など)。したがって、ユースケースに応じて、アプリケーションのページネーション方法を混ぜて一致させることができます。

    ただし、APIを構築している場合は、一貫性があり、すべてのエンドポイントに単一のページネーションアプローチを使用することを強くお勧めします。これにより、開発者はAPIの使用方法を理解し、混乱を避けることができます。

    あなたは彼らがどのエンドポイントがオフセット・ペイジネーションを使用し、どのエンドポイントを使用しているかを覚えてはいけません。

    もちろん、これは難しいルールではありません。ある特定のエンドポイントで別のページネーション方法を使用する必要がある場合は、先に進みます。ただし、開発者が理解しやすくするために、ドキュメントでそれを明確にするようにしてください。

    #preferの代わりにビデオを提供しますか?

    あなたが視覚的な学習者の方があれば、オフセットとカーソルベースのページネーションの違いをより詳細に説明するこの素晴らしいビデオを、アーロン・フランシスのこの素晴らしいビデオをチェックすることをお勧めします。

    #conclusion

    この記事では、Laravelのさまざまな種類のページネーションとそれらの使用方法を調べました。また、彼らの根底にあるSQLクエリと、アプリケーションで使用するページネーション方法を決定する方法についても検討しました。

    うまくいけば、あなたは今、あなたのLaravelアプリケーションでページネーションを使用することにもっと自信を感じるべきです。

以上がLaravelのページネーションのガイドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート