#14 Laravel基礎
ページネーション
ページネーションとは
ページネーション? データを複数ページに分けて表示する仕組み。100件のデータを1ページ10件ずつ表示するといった用途に使う。 は、大量のデータを複数ページに分けて表示する仕組みです。「1〜10件目」「11〜20件目」のように分割し、ナビゲーションリンクを自動で生成できます。
paginate() の基本
コントローラーで get() の代わりに paginate() を使うだけです。
// 📁 app/Http/Controllers/PostController.php
public function index()
{
// 1ページあたり15件で分割
$posts = Post::latest()->paginate(15);
return view('posts.index', compact('posts'));
}
ビューで $posts を使うとき:
{{-- 📁 resources/views/posts/index.blade.php --}}
@foreach ($posts as $post)
<div>
<h2>{{ $post->title }}</h2>
</div>
@endforeach
{{-- ページネーションリンクを表示 --}}
{{ $posts->links() }}
{{ $posts->links() }} だけでページナビゲーション(前へ・次へ・ページ番号)が表示されます。
URLのクエリパラメーター
paginate() は自動で ?page=2 のようなURLを生成します。
/posts?page=1 → 1〜15件目
/posts?page=2 → 16〜30件目
他の検索条件と組み合わせるときは appends() または withQueryString() を使います。
// 📁 app/Http/Controllers/PostController.php
public function index(Request $request)
{
$posts = Post::query()
->when($request->status, fn($q) => $q->where('status', $request->status))
->latest()
->paginate(15)
->withQueryString(); // ← 現在のクエリパラメーターをリンクに引き継ぐ
// 例:?status=published&page=2 のように status が維持される
return view('posts.index', compact('posts'));
}
simplePaginate
「前のページ・次のページ」のリンクだけで十分な場合(ページ番号不要)は simplePaginate() が効率的です。全件数のカウントSQLが不要になるため、大量データで速くなります。
$posts = Post::latest()->simplePaginate(15);
カスタムページネーションビュー
デフォルトのページネーションデザインはTailwind CSSに対応しています。Bootstrap用もあります。
# ページネーションのビューをカスタマイズするためにファイルを公開
php artisan vendor:publish --tag=laravel-pagination
resources/views/vendor/pagination/ にファイルが展開されます。編集するとデザインを自由に変更できます。
特定のページネーションだけ別のビューを使いたい場合:
{{ $posts->links('vendor.pagination.custom') }}
ページネーション情報の取得
ビューやコントローラーで現在のページ情報を取得できます。
$posts->currentPage(); // 現在のページ番号
$posts->lastPage(); // 最終ページ番号
$posts->total(); // 総件数
$posts->perPage(); // 1ページあたりの件数
$posts->firstItem(); // 現在ページの最初の番号(例:16)
$posts->lastItem(); // 現在ページの最後の番号(例:30)
$posts->hasMorePages(); // 次のページがあるか
使用例:
<p>{{ $posts->total() }}件中 {{ $posts->firstItem() }}〜{{ $posts->lastItem() }}件を表示</p>
whenで条件付きクエリをスッキリ書く
when() メソッドを使うと、条件付きのクエリを読みやすく書けます。
// 📁 app/Http/Controllers/PostController.php
public function index(Request $request)
{
$posts = Post::query()
// $request->status があるときだけ絞り込む
->when($request->status, fn ($q, $status) =>
$q->where('status', $status)
)
// $request->keyword があるときだけ検索する
->when($request->keyword, fn ($q, $keyword) =>
$q->where('title', 'like', "%{$keyword}%")
)
->latest()
->paginate(15)
->withQueryString();
return view('posts.index', compact('posts'));
}
まとめ
paginate(件数)でページ分割でき、{{ $posts->links() }}でナビゲーションが出るwithQueryString()で検索条件をページリンクに引き継げるsimplePaginate()はページ番号なしで大量データに向いているwhen()を使うと検索フォームの条件付きクエリをすっきり書ける
次回はLaravel Breezeを使った認証機能の導入を学びます。