The following is the Laravel tutorial column to introduce to you the Laravel project pseudo-static paging processing, I hope it will be helpful to friends in need!
I have a Laravel project that requires pseudo-static processing. The project uses Laravel's own paging component. The paging component will use Query to pass the page number in your URL. , failing to meet the pseudo-static requirements.
The effect we want for pseudo-static is roughly like this:
/software/3dmax/created_at/page-1.html
The route corresponding to Laravel is:
/software/{category}/{order}/page-{page}.html
Because Laravel routing itself supports routing parameters, there is no problem in obtaining our variables. However, Laravel's own paging component will pass your parameters using Query, so the generated paging address is as follows Kind of
/software/3dmax/created_at/page-1.html?category=3dmax&order=created_at&page=2
This is not what we need, so we need to modify Laravel's own paging component.
In Laravel, if we need pagination, we will call the paginate
method in the model, and then pass the page number of each page. The
paginate
method will call the paginator
method under Illuminate\Database\Concerns\BuildsQueries
. The paginator
method will construct an instance of Illuminate\Pagination\LengthAwarePaginator
. Illuminate\Pagination\LengthAwarePaginator
will use the url
method in Illuminate\Pagination\AbstractPaginator
to construct the request parameters and url. Now that we have found the place where the URL is generated, all we need to do is modify it here.
Laravel itself supports custom paging components, but what we are doing is not custom paging, we need to rewrite the method.
mkdir app/Pagination touch app/Pagination/LengthAwarePaginator.php
File app/Pagination/LengthAwarePaginator.php Content:
<?php namespace App\Pagination; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Pagination\LengthAwarePaginator as BasePaginator; class LengthAwarePaginator extends BasePaginator { }
First of all, Laravel’s own paging will Put the parameters in the route into Query. What we need is the parameters or put them into the address.
Modify the content under 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(); } ...
In Laravel, if we need paging, we will call the model The paginate
method in , but the paginate
method is defined under Illuminate\Database\Eloquent\Builder
. If we need to rewrite it, it will be very troublesome, and Another problem is that not all of our paging needs to be pseudo-static. For example, the data in our user center may not need pseudo-static. So we need something that can be set manually. There is a local scope in the Larave model. We can write a method staticPaginate
. When we need to use static pagination, we can Model->query ()->staticPaginate();
to call, the parameters required are similar to the pageinage
method that comes with Laravel.
We generally do not directly inherit the Model in the Laravel projectIlluminate\Database\Eloquent\Model
We usually use app The \Models
directory defines a Model base class. All models inherit from the Model base class. This is not necessary, but it is more convenient to modify the model or add public methods.
You only need to copy the contents of the paginate
method under Illuminate\Database\Eloquent\Builder
and modify it Just point to $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);
The above is the detailed content of About Laravel project pseudo-static paging processing. For more information, please follow other related articles on the PHP Chinese website!