下面由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 中我们如果需要分页,会调用 模型中的 paginate 方法,然后传递每页的页码。
现在我们找到生成 URL 的地方了,我们需要做的就是在这里修改。
Laravel 中本身支持自定义分页组件,But 我们做的不是自定义分页,我们需要对于方法进行重写。
mkdir app/Pagination touch app/Pagination/LengthAwarePaginator.php
文件 app/Pagination/LengthAwarePaginator.php 内容:
<?php namespace App\Pagination; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Pagination\LengthAwarePaginator as BasePaginator; class LengthAwarePaginator extends BasePaginator { }
首先 Laravel 自带的分页 会把路由里面的参数放到 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 方法类似。
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);
以上就是关于 Laravel 项目 伪静态分页处理的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号