You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 5.6如何实现无插件的优雅URL(Pretty URL)分页?

在Laravel中不依赖第三方包实现优雅分页URL(Pretty URL)

Absolutely! You're right that Laravel's native pagination defaults to using query strings like ?page=2, but we can totally implement clean, pretty URLs (e.g., /posts/page/2) without any third-party packages. Let's walk through the process step by step:

1. Set Up Custom Routes

First, we need to add routes that handle the pretty pagination structure. Open your routes/web.php file and add these routes (adjust the controller and path to match your application):

// Handle the first page (without the /page/1 segment)
Route::get('/posts', [PostController::class, 'index'])->name('posts.index');

// Handle pages 2 and beyond with the pretty URL structure
Route::get('/posts/page/{page}', [PostController::class, 'index'])->name('posts.index.page');

2. Modify Your Controller Logic

Next, update your controller method to accept the page parameter, fetch the appropriate data, and customize the paginator's URL generation behavior. You have two straightforward approaches:

Option A: Tweak the Built-in Paginator (Simpler)

If you're using Laravel's query builder or Eloquent paginate() method, you can override the URL resolver to generate pretty links directly:

use App\Models\Post;

public function index($page = 1)
{
    // Validate the page parameter to block invalid requests
    if (!is_numeric($page) || $page < 1) {
        abort(404);
    }

    // Fetch paginated data as usual, passing the current page
    $posts = Post::paginate(10, ['*'], 'page', $page);

    // Override the URL resolver to generate pretty links
    $posts->setUrlResolver(function ($pageNumber) {
        if ($pageNumber === 1) {
            // For the first page, use the root route (no /page/1 segment)
            return route('posts.index', request()->except('page'));
        }
        // For other pages, use the pretty URL route and preserve any existing query params
        return route('posts.index.page', array_merge(
            ['page' => $pageNumber],
            request()->except('page')
        ));
    });

    return view('posts.index', compact('posts'));
}

Option B: Manually Create a Paginator (More Control)

If you need full control over the pagination logic, create a LengthAwarePaginator instance manually:

use App\Models\Post;
use Illuminate\Pagination\LengthAwarePaginator;

public function index($page = 1)
{
    $perPage = 10;
    $offset = ($page - 1) * $perPage;
    $totalPosts = Post::count();

    // Validate page number to avoid out-of-bounds requests
    if (!is_numeric($page) || $page < 1 || $offset >= $totalPosts) {
        abort(404);
    }

    // Fetch the relevant slice of data
    $posts = Post::skip($offset)->take($perPage)->get();

    // Create the paginator instance
    $paginator = new LengthAwarePaginator(
        $posts,
        $totalPosts,
        $perPage,
        $page,
        ['pageName' => 'page']
    );

    // Set up the URL resolver for pretty links
    $paginator->setUrlResolver(function ($pageNumber) {
        $queryParams = request()->except('page');
        if ($pageNumber === 1) {
            return route('posts.index', $queryParams);
        }
        return route('posts.index.page', array_merge(['page' => $pageNumber], $queryParams));
    });

    return view('posts.index', compact('paginator'));
}

3. Render Pagination in Your View

You can use Laravel's standard pagination blade directives just like you normally would. For example, in your posts/index.blade.php:

<div class="pagination">
    {{ $posts->links() }}
</div>

The paginator will now generate links like /posts for the first page, /posts/page/2 for the second, and so on—all without any third-party packages.

Bonus: Handle Additional Query Parameters

If your page uses query parameters (like search filters), the code above already preserves them by merging request()->except('page') into the route parameters. So if you have a URL like /posts?search=laravel, the pagination links will become /posts/page/2?search=laravel—keeping your filters intact while maintaining pretty pagination URLs.

内容的提问来源于stack exchange,提问作者Jesse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:53:43