下面由教學欄目給大家介紹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
方法,然後傳遞每頁的頁碼。
paginate
方法會呼叫 Illuminate\Database\Concerns\BuildsQueries
下的paginator
方法。paginator
方法會構造一個 Illuminate\Pagination\LengthAwarePaginator
的範例。Illuminate\Pagination\LengthAwarePaginator
會使用 Illuminate\Pagination\AbstractPaginator
中的url
方法進行構造請求引數和url。現在我們找到生成 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 專案 偽靜態分頁處理的詳細內容,更多請關注TW511.COM其它相關文章!