调用分页
$data = Product::query()->paginate(100);
我们将基于 paginate 方法实现的分页进行扩展,只是修改其分页链接格式,该方法底层调用了 Illuminate\Pagination\LengthAwarePaginator 类实现分页,所以我们需要自定义一个继承自该分页器类的 app/Utils/AcademyPaginator.php,初始化代码如下:
我们要求分页格式是ProductNameList_关键字_页码
<?php
namespace app/Utils;
use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Str;
use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator as BasePaginator;
class AcademyPaginator extends BasePaginator
{
/**
* 重写页面 URL 实现代码,去掉分页中的问号,实现伪静态链接
* @param int $page
* @return string
*/
public function url($page)
{
if ($page <= 0) {
$page = 1;
}
// 移除路径尾部的/
$path = rtrim($this->path, '_');
if( preg_match('/\/search_[\s\S]*_\d+/',$path,$matches,PREG_OFFSET_CAPTURE)){
preg_match('/\/search_[\s\S]*_\d+/',$path,$matches,PREG_OFFSET_CAPTURE);
$path_arr = explode('_',$matches[0][0]);
$url = preg_replace('/\/search_[\s\S]*_\d+/', '/search_'.$path_arr[1].'_' . $page, $path);
}else if( preg_match('/\/supplierList_[\s\S]*_\d+/',$path,$matches,PREG_OFFSET_CAPTURE)){
preg_match('/\/supplierList_[\s\S]*_\d+/',$path,$matches,PREG_OFFSET_CAPTURE);
$path_arr = explode('_',$matches[0][0]);
$url = preg_replace('/\/supplierList_[\s\S]*_\d+/', '/supplierList_'.$path_arr[1].'_' . $page, $path);
}else if( preg_match('/\/productCasList_[\s\S]*_\d+/',$path,$matches,PREG_OFFSET_CAPTURE)){
preg_match('/\/productCasList_[\s\S]*_\d+/',$path,$matches,PREG_OFFSET_CAPTURE);
$path_arr = explode('_',$matches[0][0]);
$url = preg_replace('/\/productCasList_[\s\S]*_\d+/', '/productCasList_'.$path_arr[1].'_' . $page, $path);
}else if( preg_match('/\/productNameList_[\s\S]*_\d+/',$path,$matches,PREG_OFFSET_CAPTURE)){
preg_match('/\/productNameList_[\s\S]*_\d+/',$path,$matches,PREG_OFFSET_CAPTURE);
$path_arr = explode('_',$matches[0][0]);
$url = preg_replace('/\/productNameList_[\s\S]*_\d+/', '/productNameList_'.$path_arr[1].'_' . $page, $path);
}else{
$url = '';
}
// // 如果路径中包含分页信息则正则替换页码,否则将页码信息追加到路径末尾
// dd($this->query);
// if (preg_match('/\/search_[\s\S]*_\d+/', $path)) {
// $path = preg_replace('/\/search_[\s\S]*_\d+/', '/search_[\s\S]*_' . $page, $path);
// } else {
// $path .= '/search_' . $page;
// }
// $this->path = $path;
//
// if ($this->query) {
// $this_path_arr = explode('_',$this->path);
// $path = $this_path_arr[0];
// foreach($this->query as $val){
// $path .= '_'.$val;
// }
// $url = $path.'_'.$this_path_arr[1].$this->buildFragment();
// } elseif ($this->fragment) {
// $url = $this->path . $this->buildFragment();
// } else {
// $url = $this->path;
// }
return $url;
}
/**
* 重写当前页设置方法
*
* @param int $currentPage
* @param string $pageName
* @return int
*/
protected function setCurrentPage($currentPage, $pageName)
{
if (!$currentPage && preg_match('/\/page_(\d+)/', $this->path, $matches)) {
$currentPage = $matches[1];
}
return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1;
}
/**
* 将新增的分页方法注册到查询构建器中,以便在模型实例上使用
* 注册方式:
* 在 AppServiceProvider 的 boot 方法中注册:AcademyPaginator::rejectIntoBuilder();
* 使用方式:
* 将之前代码中在模型实例上调用 paginate 方法改为调用 seoPaginate 方法即可:
*/
public static function injectIntoBuilder()
{
\Laravel\Scout\Builder::macro('seoPaginate', function ($perPage,$currentPage=1,$pageName='page') {
$perPage = $perPage ?: $this->model->getPerPage();
$engine = $this->engine();
$items = $this->model->newCollection($engine->map(
$this, $rawResults = $engine->paginate($this, $perPage, $currentPage), $this->model
)->all());
$options = [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
];
$total = $this->getTotalCount($rawResults);
return Container::getInstance()->makeWith(AcademyPaginator::class, compact(
'items', 'total', 'perPage', 'currentPage', 'options'
));
});
}
}
这样,在模型实例上调用 seoPaginate 方法,将通过 AcademyPaginator 进行分页,最后我们在 AppServiceProvider 的 boot 方法中全局调用这个注入:
AcademyPaginator::injectIntoBuilder();
接下来,就可以在自己的代码中编写以下这种代码实现伪静态分页链接了:
$data = Product::query()->seoPaginate(100,$page);