Maison  >  Article  >  cadre php  >  À propos du traitement de pagination pseudo-statique du projet Laravel

À propos du traitement de pagination pseudo-statique du projet Laravel

藏色散人
藏色散人avant
2021-02-20 17:27:273225parcourir
Ce qui suit est introduit par

Laravel La colonne du didacticiel présentera le traitement de pagination pseudo-statique du projet Laravel, j'espère que cela sera utile aux amis de besoin!

J'ai un projet Laravel qui nécessite un traitement pseudo-statique. Le projet utilise le propre composant de pagination de Laravel, qui utilisera Query pour transmettre le numéro de page dans votre URL, sans parvenir à répondre au pseudo. -exigences statiques.

L'effet souhaité

L'effet que nous souhaitons pour le pseudo-statique ressemble à peu près à ceci :

 /software/3dmax/created_at/page-1.html
La route correspondante pour Laravel est :

/software/{category}/{order}/page-{page}.html
Étant donné que le routage Laravel lui-même prend en charge les paramètres de routage, il n'y a aucun problème pour obtenir nos variables. Cependant, le propre composant de pagination de Laravel transmettra vos paramètres dans Query, donc l'adresse de pagination générée est la suivante Type de

 /software/3dmax/created_at/page-1.html?category=3dmax&order=created_at&page=2
Ceci. n'est pas ce dont nous avons besoin, nous devons donc modifier le composant de pagination fourni avec Laravel.

Composant de pagination Laravel

Dans Laravel, si nous avons besoin d'une pagination, nous appellerons la méthode

dans le modèle, puis transmettrons le numéro de page de chaque page. La méthode paginate

  • appellera la méthode paginate sous IlluminateDatabaseConcernsBuildsQueries. La méthode paginator
  • construira une instance de paginator. IlluminatePaginationLengthAwarePaginator
  • utilisera la méthode IlluminatePaginationLengthAwarePaginator dans IlluminatePaginationAbstractPaginator pour construire les paramètres et l'URL de la requête. url
Maintenant que nous avons trouvé où l'URL est générée, il ne nous reste plus qu'à la modifier ici.

Réécrire le composant de pagination

Laravel lui-même prend en charge les composants de pagination personnalisés, mais ce que nous faisons n'est pas une pagination personnalisée, nous devons réécrire la méthode.

Créer la classe lengthAwarePaginator

mkdir app/Pagination
touch app/Pagination/LengthAwarePaginator.php

File app/Pagination/LengthAwarePaginator.php Contenu :

<?php

namespace App\Pagination;

use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Illuminate\Pagination\LengthAwarePaginator as BasePaginator;

class LengthAwarePaginator extends BasePaginator
{
}

Réécrire la méthode Url

Tout d'abord, celle de Laravel la pagination mettra les paramètres de l'itinéraire dans la requête. Ce dont nous avons besoin, ce sont les paramètres ou les mettrons dans l'adresse.

    Obtenir tous les paramètres de requête
  • Déterminer s'il existe des paramètres de routage liés dans la route de la page qui doivent être paginés
  • Sinon, nous utiliserons Laravel lui-même Pagination
  • S'il y en a une, nous construirons l'adresse via les paramètres de routage et de routage, et la supprimerons des paramètres de requête
  • Jugerons s'il y a des paramètres dans les paramètres de requête actuels. nous sommes les mêmes qu'avant.
Modifiez le contenu sous 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();
    }

    ...
Utilisez un composant de pagination personnalisé

Dans Laravel, si nous avons besoin d'une pagination, nous appellerons la méthode modèle

dans , mais la méthode paginate est définie sous paginate Si nous devons la réécrire, ce sera très gênant. Un autre problème est que toutes nos paginations n'ont pas besoin d'être pseudo-statiques. par exemple, les données de notre centre utilisateur peuvent ne pas avoir besoin de données pseudo-statiques. Nous avons donc besoin de quelque chose qui peut être défini manuellement. Il y a une portée locale dans le modèle Larave. Nous pouvons écrire une méthode IlluminateDatabaseEloquentBuilder Lorsque nous avons besoin d'utiliser une pagination statique, nous pouvons l'appeler avec staticPaginate. Laravel La méthode Model->query()->staticPaginate(); intégrée est similaire. pageinage

Fichier de classe de base du modèle public

Nous n'héritons généralement pas directement du modèle dans le projet Laravel

Nous définissons généralement une classe de base du modèle dans le répertoire IlluminateDatabaseEloquentModel, et tous les modèles. L'héritage de la classe de base Model n'est pas nécessaire, mais cela est plus pratique pour modifier le modèle ou ajouter des méthodes publiques. appModels

Définissez la portée locale dans le modèle

Il vous suffit de copier le contenu de la méthode

sous IlluminateDatabaseEloquentBuilder et de modifier le pointeur de 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,
        ]);
    }

    ...
Remplacer le composant de pagination personnalisé

# 替换
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'
        ));
    }

    ...

Utiliser le composant de pagination statique dans le projet

Model::query()->staticPaginate($pageSize);

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer