Heim >PHP-Framework >Laravel >Über die pseudostatische Paging-Verarbeitung des Laravel-Projekts

Über die pseudostatische Paging-Verarbeitung des Laravel-Projekts

藏色散人
藏色散人nach vorne
2021-02-20 17:27:273294Durchsuche

vorgestellt, um die pseudostatische Paginierungsverarbeitung des Laravel-Projekts vorzustellen. Ich hoffe, es wird den Freunden in Not helfen! Ich habe ein Laravel-Projekt, das eine pseudostatische Verarbeitung erfordert. Die Paging-Komponente verwendet Query, um die Seitenzahl in Ihrer URL zu übergeben, was keine pseudostatische Verarbeitung erreichen kann. Der gewünschte Effekt lautet ungefähr so: Überhaupt kein Problem, aber die integrierte Paging-Komponente von Laravel übergibt Ihre Parameter in der Abfrage, sodass die generierte Paging-Adresse wie folgt lautet:

 /software/3dmax/created_at/page-1.html
Das ist nicht das, was wir brauchen, also müssen wir die integrierte Paging-Komponente von Laravel verwenden Paging-Komponente.

Laravel-Paginierungskomponente

Wenn wir in Laravel eine Paginierung benötigen, rufen wir die Methode paginate im Modell auf und übergeben dann die Seitenzahl jeder Seite.

  • Die Methode paginate ruft die Methode paginator unter IlluminateDatabaseConcernsBuildsQueries auf.
  • Die Methode paginator erstellt eine Instanz von IlluminatePaginationLengthAwarePaginator.
  • IlluminatePaginationLengthAwarePaginator verwendet die Methode url in IlluminatePaginationAbstractPaginator, um die Anforderungsparameter und die URL zu erstellen.

Da wir nun den Ort gefunden haben, an dem die URL generiert wird, müssen wir sie nur noch hier ändern.

Schreiben Sie die Paging-Komponente neu

Laravel selbst unterstützt benutzerdefinierte Paging-Komponenten, aber was wir tun, ist kein benutzerdefiniertes Paging, wir müssen die Methode neu schreiben.

Erstellen Sie die LengthAwarePaginator-Klasse.

/software/{category}/{order}/page-{page}.html
die Adresse.
  • Alle Abfrageparameter abrufen
  • Bestimmen Sie, ob in der Seitenroute gebundene Routing-Parameter vorhanden sind, die paginiert werden müssen
  • Wenn nicht, verwenden wir das Paging von Laravel selbst
  • Wenn es eine gibt, erstellen wir die Adresse durch Routing und Routing-Parameter und entfernen sie aus den Abfrageparametern
  • Beurteilen Sie, ob in den aktuellen Abfrageparametern welche vorhanden sind. Die Parameter, falls vorhanden, sind die gleichen wie zuvor.

Ändern Sie den Inhalt unter app/Pagination/LengthAwarePaginator.php:

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

Verwenden Sie eine benutzerdefinierte Paginierungskomponentepaginate 方法,然后传递每页的页码。

  • paginate 方法会调用 IlluminateDatabaseConcernsBuildsQueries 下的paginator方法。
  • paginator 方法会构造一个 IlluminatePaginationLengthAwarePaginator的实例。
  • IlluminatePaginationLengthAwarePaginator 会使用 IlluminatePaginationAbstractPaginator 中的url方法进行构造请求参数和url。

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

重写分页组件

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

创建 LengthAwarePaginator 类

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
{
}

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

公共的Model 基类文件

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

在模型中定义本地作用域

你只需要拷贝 IlluminateDatabaseEloquentBuilder下的paginate方法的内容并修改$this

Wenn wir in Laravel eine Paginierung benötigen, rufen wir paginate auf Modellcode>-Methode, aber die <code>paginate-Methode ist unter IlluminateDatabaseEloquentBuilder definiert. Wenn wir sie neu schreiben müssen, wird es sehr mühsam sein, und ein weiteres Problem ist, dass nicht alle von uns Für das Paging ist eine Pseudostatik erforderlich. Beispielsweise ist für die Daten in unserem Benutzercenter möglicherweise keine Pseudostatik erforderlich. Wir benötigen also etwas, das manuell festgelegt werden kann. Wir können eine Methode staticPaginate schreiben ; query()->staticPaginate(); zum Aufrufen, die erforderlichen Parameter ähneln der eigenen pageinage-Methode von Laravel.

Öffentliche Modell-Basisklassendatei

Modell im Laravel-Projekt Wir erben im Allgemeinen nicht direkt IlluminateDatabaseEloquentModel. Wir definieren normalerweise eine Modell-Basisklasse im Verzeichnis appModels, alle Modelle Von der Model-Basisklasse erben. Dies ist nicht erforderlich, es ist jedoch bequemer, das Modell zu ändern oder öffentliche Methoden hinzuzufügen. 🎜🎜Definieren Sie den lokalen Bereich im Modell🎜🎜Sie müssen nur den Inhalt der paginate-Methode unter IlluminateDatabaseEloquentBuilder kopieren und den Zeiger von $thisändern > Das ist es🎜
...

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,
        ]);
    }

    ...
🎜Ersetzen Sie die benutzerdefinierte Paging-Komponente🎜
# 替换
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'
        ));
    }

    ...
🎜Verwenden Sie die statische Paging-Komponente im Projekt🎜
Model::query()->staticPaginate($pageSize);

Das obige ist der detaillierte Inhalt vonÜber die pseudostatische Paging-Verarbeitung des Laravel-Projekts. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:learnku.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen