Documentation Index Fetch the complete documentation index at: https://kawax.biz/llms.txt
Use this file to discover all available pages before exploring further.
ページネーションとは
Laravelのページネーションは、クエリビルダーおよびEloquent ORMと統合されており、設定なしで使い始めることができます。現在のページはHTTPリクエストの page クエリパラメーターから自動的に取得され、生成されたリンクにも自動で付加されます。
デフォルトのHTMLはTailwind CSSに対応しており、Bootstrap CSSも選択できます。
3種類のページネーション
メソッド 返り値 特徴 paginate()LengthAwarePaginator総件数を取得。ページ番号リンクを生成 simplePaginate()Paginator総件数を取得しない。「前へ」「次へ」のみ cursorPaginate()CursorPaginatorカーソルベース。大量データに最適
基本的な使い方
クエリビルダーのページネーション
use Illuminate\Support\Facades\ DB ;
// 1ページあたり15件で取得
$users = DB :: table ( 'users' ) -> paginate ( 15 );
Eloquentのページネーション
use App\Models\ User ;
$users = User :: paginate ( 15 );
// 条件付き
$users = User :: where ( 'votes' , '>' , 100 ) -> paginate ( 15 );
simplePaginate
総件数のカウントクエリが不要な場合(「前へ」「次へ」リンクのみ表示)は simplePaginate() を使うと効率的です。
$users = DB :: table ( 'users' ) -> simplePaginate ( 15 );
$users = User :: where ( 'active' , true ) -> simplePaginate ( 15 );
「全部で何件中何件目」という表示が不要なら simplePaginate() を選びましょう。paginate() は COUNT(*) クエリを追加で実行するため、simplePaginate() の方が高速です。
cursorPaginate(カーソルページネーション)
カーソルページネーションはOFFSET句の代わりにWHERE句を使うため、大量データに対して高いパフォーマンスを発揮します。無限スクロールのUIに特に適しています。
// orderBy が必須
$users = DB :: table ( 'users' ) -> orderBy ( 'id' ) -> cursorPaginate ( 15 );
$users = User :: where ( 'active' , true ) -> cursorPaginate ( 15 );
生成されるURLにはページ番号ではなくカーソル文字列が入ります。
http://example.com/users?cursor=eyJpZCI6MTUsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0
カーソルページネーションを使うには orderBy が必須です。また、並び順のカラムはページネーション対象のテーブルに属している必要があります。
OFFSETとカーソルの比較
-- paginate() / simplePaginate() — OFFSETを使う
SELECT * FROM users ORDER BY id ASC LIMIT 15 OFFSET 15 ;
-- cursorPaginate() — WHERE句を使う(インデックスが効く)
SELECT * FROM users WHERE id > 15 ORDER BY id ASC LIMIT 15 ;
カーソルページネーションはインデックスが有効活用され、データが頻繁に追加・削除される場合もレコードの重複・欠落が起きにくいという利点があります。ただし、ページ番号リンクの生成はできず、「前へ」「次へ」のみです。
コントローラーでの実装
<? php
namespace App\Http\Controllers ;
use App\Models\ User ;
use Illuminate\View\ View ;
class UserController extends Controller
{
public function index () : View
{
$users = User :: orderBy ( 'name' ) -> paginate ( 20 );
return view ( 'users.index' , compact ( 'users' ));
}
}
Bladeでのページネーションリンク表示
< div class = "container" >
@foreach ( $users as $user )
< p > {{ $user -> name }} </ p >
@endforeach
</ div >
{{-- ページネーションリンクを出力(Tailwind CSS対応) --}}
{{ $users -> links () }}
links() メソッドが自動でページリンクのHTMLを生成します。現在のページの前後3ページ分のリンクが表示されます。
表示するリンク数の調整
onEachSide() で現在のページの前後に表示するリンク数を変更できます。
{{-- 現在ページの前後5ページ分を表示 --}}
{{ $users -> onEachSide ( 5 ) -> links () }}
1ページあたりの件数をリクエストから受け取る
public function index ( Request $request ) : View
{
$perPage = $request -> integer ( 'per_page' , 15 );
$perPage = min ( max ( $perPage , 1 ), 100 ); // 1〜100の範囲に制限
$users = User :: paginate ( $perPage );
return view ( 'users.index' , compact ( 'users' ));
}
1ページに複数のページネーターを表示する
同一画面に2つのページネーターを表示する場合、両方が page パラメーターを使うと競合します。第3引数でパラメーター名を変更します。
$users = User :: paginate (
perPage : 15 ,
columns : [ '*' ],
pageName : 'users'
);
$posts = Post :: paginate (
perPage : 10 ,
columns : [ '*' ],
pageName : 'posts'
);
URLのカスタマイズ
ベースURLの変更
$users = User :: paginate ( 15 );
// /admin/users?page=N 形式のURLを生成
$users -> withPath ( '/admin/users' );
クエリパラメーターの追加
// sort=votes を各ページリンクに追加
$users -> appends ([ 'sort' => 'votes' ]);
// 現在のリクエストの全クエリパラメーターを引き継ぐ
$users -> withQueryString ();
ハッシュフラグメントの追加
// URLの末尾に #users を追加
$users -> fragment ( 'users' );
APIレスポンス(JSON出力)
ページネーターをルートやコントローラーからそのまま返すと、自動的にJSONに変換されます。
use App\Models\ User ;
Route :: get ( '/api/users' , function () {
return User :: paginate ( 15 );
});
レスポンスのJSON形式:
{
"total" : 50 ,
"per_page" : 15 ,
"current_page" : 1 ,
"last_page" : 4 ,
"first_page_url" : "http://example.com/api/users?page=1" ,
"last_page_url" : "http://example.com/api/users?page=4" ,
"next_page_url" : "http://example.com/api/users?page=2" ,
"prev_page_url" : null ,
"path" : "http://example.com/api/users" ,
"from" : 1 ,
"to" : 15 ,
"data" : [
{ "id" : 1 , "name" : "山田太郎" },
{ "id" : 2 , "name" : "鈴木花子" }
]
}
APIリソースとの組み合わせ
paginate() の結果をAPIリソースコレクションでラップする場合は UserResource::collection() に渡します。
use App\Http\Resources\ UserResource ;
use App\Models\ User ;
Route :: get ( '/api/users' , function () {
$users = User :: paginate ( 15 );
return UserResource :: collection ( $users );
});
UserResource::collection() にページネーターを渡すと、ページネーション情報がメタデータとして自動で付加されます。
cursorPaginate() のJSONにはページ番号ではなく next_cursor と prev_cursor が含まれます。APIクライアントはこれらの値を次のリクエストの cursor パラメーターとして使います。
カスタムページネーションビュー
ビューファイルに直接指定
{{-- カスタムビューでリンクを出力 --}}
{{ $paginator -> links ( 'vendor.pagination.custom' ) }}
{{-- データを追加で渡す --}}
{{ $paginator -> links ( 'vendor.pagination.custom' , [ 'theme' => 'dark' ]) }}
デフォルトビューをカスタムファイルに変更
まず公式のビューを公開してからカスタマイズします。
php artisan vendor:publish --tag=laravel-pagination
resources/views/vendor/pagination/ に以下のファイルが生成されます。
tailwind.blade.php — デフォルト(Tailwind CSS用)
bootstrap-5.blade.php — Bootstrap 5用
simple-tailwind.blade.php — simplePaginate用
…
tailwind.blade.php を直接編集するか、新しいビューを作成して AppServiceProvider で指定します。
use Illuminate\Pagination\ Paginator ;
public function boot () : void
{
Paginator :: defaultView ( 'vendor.pagination.custom' );
Paginator :: defaultSimpleView ( 'vendor.pagination.simple-custom' );
}
Bootstrap CSSを使う
TailwindではなくBootstrapを使う場合は AppServiceProvider の boot() で指定します。
use Illuminate\Pagination\ Paginator ;
public function boot () : void
{
Paginator :: useBootstrapFive (); // Bootstrap 5
// Paginator::useBootstrapFour(); // Bootstrap 4
}
手動でページネーターを作成する
配列などの既存データにページネーションを適用したい場合、ページネータークラスを直接インスタンス化します。
use Illuminate\Pagination\ LengthAwarePaginator ;
$items = collect ( range ( 1 , 200 )) -> map ( fn ( $i ) => [ 'id' => $i , 'name' => "アイテム{ $i }" ]);
$perPage = 15 ;
$currentPage = request () -> integer ( 'page' , 1 );
$paginator = new LengthAwarePaginator (
items : $items -> forPage ( $currentPage , $perPage ),
total : $items -> count (),
perPage : $perPage ,
currentPage : $currentPage ,
options : [ 'path' => request () -> url ()]
);
よく使うインスタンスメソッド
$paginator = User :: paginate ( 15 );
$paginator -> currentPage (); // 現在のページ番号
$paginator -> lastPage (); // 最後のページ番号(simplePaginate では使用不可)
$paginator -> total (); // 総件数(simplePaginate では使用不可)
$paginator -> perPage (); // 1ページあたりの件数
$paginator -> count (); // 現在ページの件数
$paginator -> firstItem (); // 現在ページの最初のアイテムの番号
$paginator -> lastItem (); // 現在ページの最後のアイテムの番号
$paginator -> hasPages (); // 複数ページが存在するか
$paginator -> hasMorePages (); // 次のページが存在するか
$paginator -> onFirstPage (); // 最初のページか
$paginator -> onLastPage (); // 最後のページか
$paginator -> nextPageUrl (); // 次のページURL
$paginator -> previousPageUrl (); // 前のページURL
$paginator -> url ( 3 ); // ページ3のURL
$paginator -> items (); // 現在ページのアイテム配列
まとめ
paginate() — 総件数とページ番号リンクが必要な場合(一般的なリスト画面)
simplePaginate() — 「前へ」「次へ」リンクのみで十分な場合(高速)
cursorPaginate() — 大量データ・無限スクロール・頻繁な書き込みがある場合(最高パフォーマンス)
@foreach ( $users as $user )
< p > {{ $user -> name }} </ p >
@endforeach
{{ $users -> links () }}
paginate() の結果をビューに渡し、links() でページリンクを出力するだけです。
現在のページは page クエリパラメーターから自動で検出されます。
ページネーターをルートから直接返すと自動的にJSONに変換されます。
APIリソースと組み合わせるには UserResource::collection($paginator) を返します。
レスポンスには data(レコード配列)と各種メタ情報が含まれます。