0

0

关于 Laravel 项目 伪静态分页处理

藏色散人

藏色散人

发布时间:2021-02-20 17:27:27

|

3678人浏览过

|

来源于learnku

转载

下面由Laravel教程栏目给大家介绍Laravel 项目 伪静态分页处理  ,希望对需要的朋友有所帮助!

手上有个 Laravel 的项目,要求做伪静态处理,项目中使用了 Laravel 自带的分页组件,分页组件分页会在你的 URL 用 Query 的方式做页码的传递,达不到伪静态的要求。

想要的效果

我们伪静态想要的效果大体是这样的:

 /software/3dmax/created_at/page-1.html

对应 Laravel 的路由是:

/software/{category}/{order}/page-{page}.html

因为 Laravel 路由本身是支持路由参数的,所以说 我们变量的获取是完全没有问题的,但是 Laravel 自带的分页组件会将你的 参数 用 Query 的方式做传递,所以生成的分页地址是下面这种

 /software/3dmax/created_at/page-1.html?category=3dmax&order=created_at&page=2

这不是我们需要的,所以我们需要对 Laravel 自带的分页组件进行修改。

Laravel 分页组件

在 Laravel 中我们如果需要分页,会调用 模型中的 paginate 方法,然后传递每页的页码。

  • paginate 方法会调用 Illuminate\Database\Concerns\BuildsQueries 下的paginator方法。
  • paginator 方法会构造一个 Illuminate\Pagination\LengthAwarePaginator的实例。
  • Illuminate\Pagination\LengthAwarePaginator 会使用 Illuminate\Pagination\AbstractPaginator 中的url方法进行构造请求参数和url。

现在我们找到生成 URL 的地方了,我们需要做的就是在这里修改。

重写分页组件

Laravel 中本身支持自定义分页组件,But 我们做的不是自定义分页,我们需要对于方法进行重写。

创建 LengthAwarePaginator 类

mkdir app/Pagination
touch app/Pagination/LengthAwarePaginator.php

文件 app/Pagination/LengthAwarePaginator.php 内容:

Khroma
Khroma

AI调色盘生成工具

下载
<?php

namespace App\Pagination;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Pagination\LengthAwarePaginator as BasePaginator;

class LengthAwarePaginator extends BasePaginator
{
}

重写 Url 方法

首先 Laravel 自带的分页 会把路由里面的参数放到 Query中,我们需要的是 参数还是放到地址中。

  • 获取到所有的 query 参数
  • 判断需要分页的页面路由中是否有绑定的路由参数
  • 如果没有的话,我们就走 Laravel 本身的分页
  • 如果有的话,我们就通过路由和路由参数进行构建地址,并把它从 query 参数中剔除
  • 判断下当前的 query 参数中是否还有参数,如果还有的话,我们就和之前一样。

修改 app/Pagination/LengthAwarePaginator.php下内容:

...

public function url($page)
    {
        if ($page <= 0) {
            $page = 1;
        }

        $parameters = [$this->pageName => $page];

        if (count($this->query) > 0) {
            $parameters = array_merge($this->query, $parameters);
        }

        //判断的参数是否在 路由中 需要绑定的数据
        $params = \request()->route()->parameters();

        if (!empty($params)) {
            foreach ($parameters as $key => $parameter) {
                if (isset($params[$key])) {
                    $params[$key] = $parameter;
                    unset($parameters[$key]);
                }
            }

            $path = route(\request()->route()->getAction('as'), $params);
        } else {
            $path = $this->path;
        }

        // 判断是否有参数
        if (empty(Arr::query($parameters))) {
            return $path . $this->buildFragment();
        }

        return $path
            . (Str::contains($this->path, '?') ? '&' : '?')
            . Arr::query($parameters)
            . $this->buildFragment();
    }

    ...

使用自定义的分页组件

在 Laravel 中我们如果需要分页,会调用 模型中的 paginate 方法,但是paginate方法的定义在Illuminate\Database\Eloquent\Builder下,如果我们需要重写的话,会很麻烦,并且还有一个问题就是,并不是我们所有的分页都是需要伪静态的,比如我们用户中心的数据可能不太需要伪静态。所以我们需要一个可以手动设置的东西,Larave 模型中有一个 本地作用域,我们可以写一个方法staticPaginate,当需要使用静态分页的时候,我们可以Model->query()->staticPaginate(); 来调用,所需要的参数和 Laravel 自带的 pageinage 方法类似。

公共的Model 基类文件

Laravel项目中的 Model 我们一般不会直接继承Illuminate\Database\Eloquent\Model 我们一般都在 app\Models 目录定义一个 Model  基类,所有的模型都继承自 Model 基类,这并不是必须的,只是这样的话对于模型修改,或添加公共的方法比较方便。

在模型中定义本地作用域

你只需要拷贝 Illuminate\Database\Eloquent\Builder下的paginate方法的内容并修改$this的指向就可以了

...

use Illuminate\Pagination\Paginator;
# Laravel 自带的。
use Illuminate\Contracts\Pagination\LengthAwarePaginator;

...

   /**
     * 自定义静态分页
     * @author kingofzihua
     * @param Builder $builder
     * @param int $perPage
     * @param array $columns
     * @param string $pageName
     * @param int|null $page
     * @return LengthAwarePaginator
     *
     * @throws \InvalidArgumentException
     */
    public function scopeStaticPaginate($builder, $perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
    {
        if (request('page')) {
            request()->offsetSet('page', request('page'));
        }

        $page = $page ?: Paginator::resolveCurrentPage($pageName);

        $perPage = $perPage ?: $builder->getModel()->getPerPage();

        $results = ($total = $builder->toBase()->getCountForPagination())
            ? $builder->forPage($page, $perPage)->get($columns)
            : $builder->getModel()->newCollection();
        return $this->paginator($results, $total, $perPage, $page, [
            'path' => Paginator::resolveCurrentPath(),
            'pageName' => $pageName,
        ]);
    }

    ...

替换自定义的分页组件

# 替换
use App\Pagination\LengthAwarePaginator;
# --- use  Illuminate\Contracts\Pagination\LengthAwarePaginator;  // 注释

...

   /**
     *
     * @param \Illuminate\Support\Collection $items
     * @param int $total
     * @param int $perPage
     * @param int $currentPage
     * @param array $options
     * @return LengthAwarePaginator
     */
    protected function paginator($items, $total, $perPage, $currentPage, $options)
    {
        return Container::getInstance()->makeWith(LengthAwarePaginator::class, compact(
            'items', 'total', 'perPage', 'currentPage', 'options'
        ));
    }

    ...

在项目中使用静态分页组件

Model::query()->staticPaginate($pageSize);

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
laravel组件介绍
laravel组件介绍

laravel 提供了丰富的组件,包括身份验证、模板引擎、缓存、命令行工具、数据库交互、对象关系映射器、事件处理、文件操作、电子邮件发送、队列管理和数据验证。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

341

2024.04.09

laravel中间件介绍
laravel中间件介绍

laravel 中间件分为五种类型:全局、路由、组、终止和自定。想了解更多laravel中间件的相关内容,可以阅读本专题下面的文章。

295

2024.04.09

laravel使用的设计模式有哪些
laravel使用的设计模式有哪些

laravel使用的设计模式有:1、单例模式;2、工厂方法模式;3、建造者模式;4、适配器模式;5、装饰器模式;6、策略模式;7、观察者模式。想了解更多laravel的相关内容,可以阅读本专题下面的文章。

795

2024.04.09

thinkphp和laravel哪个简单
thinkphp和laravel哪个简单

对于初学者来说,laravel 的入门门槛较低,更易上手,原因包括:1. 更简单的安装和配置;2. 丰富的文档和社区支持;3. 简洁易懂的语法和 api;4. 平缓的学习曲线。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

386

2024.04.10

laravel入门教程
laravel入门教程

本专题整合了laravel入门教程,想了解更多详细内容,请阅读专题下面的文章。

146

2025.08.05

laravel实战教程
laravel实战教程

本专题整合了laravel实战教程,阅读专题下面的文章了解更多详细内容。

85

2025.08.05

laravel面试题
laravel面试题

本专题整合了laravel面试题相关内容,阅读专题下面的文章了解更多详细内容。

84

2025.08.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

723

2026.03.04

C++多线程并发控制与线程安全设计实践
C++多线程并发控制与线程安全设计实践

本专题围绕 C++ 在高性能系统开发中的并发控制技术展开,系统讲解多线程编程模型与线程安全设计方法。内容包括互斥锁、读写锁、条件变量、原子操作以及线程池实现机制,同时结合实际案例分析并发竞争、死锁避免与性能优化策略。通过实践讲解,帮助开发者掌握构建稳定高效并发系统的关键技术。

2

2026.03.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Laravel---API接口
Laravel---API接口

共7课时 | 0.7万人学习

PHP自制框架
PHP自制框架

共8课时 | 0.6万人学习

PHP面向对象基础课程(更新中)
PHP面向对象基础课程(更新中)

共12课时 | 0.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号