Laravel 프로젝트 의사 정적 페이징 처리 정보

藏色散人
풀어 주다: 2021-02-22 09:16:06
앞으로
3230명이 탐색했습니다.

튜토리얼 칼럼에서 소개한 내용입니다. 도움이 필요한 친구들에게 도움이 되길 바랍니다! 저는 의사 정적 처리가 필요한 Laravel 프로젝트를 가지고 있습니다. 이 프로젝트는 Laravel의 자체 페이징 구성 요소를 사용하여 의사 정적 처리 요구 사항을 충족할 수 없는 URL의 페이지 번호를 전달합니다.

원하는 효과

pseudo-static에 대해 원하는 효과는 대략 다음과 같습니다:
 /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 Pagination Component

Laravel에서는 페이지 매김이 필요한 경우 모델에서 paginate 메소드를 호출한 다음 각 페이지의 페이지 번호를 전달합니다.

  • paginate 메서드는 IlluminateDatabaseConcernsBuildsQueries 아래의 paginator 메서드를 호출합니다.
  • paginator 메소드는 IlluminatePaginationLengthAwarePaginator의 인스턴스를 생성합니다.
  • IlluminatePaginationLengthAwarePaginatorIlluminatePaginationAbstractPaginatorurl 메서드를 사용하여 요청 매개변수와 URL을 구성합니다.

이제 URL이 생성되는 위치를 찾았으므로 여기에서 수정하기만 하면 됩니다.

페이징 구성 요소 다시 작성paginate 方法,然后传递每页的页码。

  • 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

Laravel 자체는 사용자 정의 페이징 구성 요소를 지원하지만 우리가 하는 일은 사용자 정의 페이징이 아니므로 메서드를 다시 작성해야 합니다.

LengthAwarePaginator 클래스 만들기

...

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

    ...
로그인 후 복사

파일 app/Pagination/LengthAwarePaginator.php 내용: 🎜
# 替换
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'
        ));
    }

    ...
로그인 후 복사
🎜Url 메서드 다시 작성🎜🎜우선, Laravel의 자체 페이징은 경로에 있는 매개변수를 쿼리에 넣습니다. ? 🎜
  • 모든 쿼리 매개변수 가져오기
  • 페이지 경로에 페이지 지정이 필요한 바인딩된 라우팅 매개변수가 있는지 확인
  • 그렇지 않은 경우 Laravel 자체 페이징을 사용합니다.
  • 있는 경우 라우팅 및 라우팅 매개변수를 통해 주소를 구성하고 쿼리 매개변수에서 제거합니다.
  • 현재 쿼리 매개변수에 존재 여부를 판단하는 매개변수는, 있다면 이전과 동일합니다.
🎜app/Pagination/LengthAwarePaginator.php에서 콘텐츠를 수정하세요. 🎜
Model::query()->staticPaginate($pageSize);
로그인 후 복사
🎜사용자 정의 페이지 매기기 구성 요소를 사용하세요🎜🎜Laravel에서 페이지 매기기가 필요한 경우 다음에서 paginate를 호출합니다. model code> 메서드를 사용하지만 paginate 메서드는 IlluminateDatabaseEloquentBuilder 아래에 정의되어 있습니다. 이를 다시 작성해야 한다면 매우 번거로울 것이며 또 다른 문제는 우리 모두가 그렇지 않다는 것입니다. 페이징에는 의사 정적이 필요합니다. 예를 들어 사용자 센터의 데이터에는 의사 정적이 필요하지 않을 수 있습니다. 따라서 수동으로 설정할 수 있는 것이 필요합니다. Larave 모델에는 staticPaginate 메서드를 작성할 수 있습니다. 정적 페이지 매김을 사용해야 하는 경우 Model-&gt를 수행할 수 있습니다. ; query()->staticPaginate();를 호출하는 데 필요한 매개변수는 Laravel의 자체 pageinage 메소드와 유사합니다. 🎜🎜Public Model 기본 클래스 파일🎜🎜Laravel 프로젝트의 모델 우리는 일반적으로 IlluminateDatabaseEloquentModel을 직접 상속하지 않습니다. 우리는 일반적으로 appModels 디렉토리에 Model 기본 클래스를 정의합니다. Model 기본 클래스에서 상속합니다. 필수는 아니지만 모델을 수정하거나 공용 메서드를 추가하는 것이 더 편리합니다. 🎜🎜모델에서 로컬 범위를 정의하세요🎜🎜IlluminateDatabaseEloquentBuilder에서 paginate 메서드의 내용을 복사하고 $this의 포인터를 수정하기만 하면 됩니다. > 그게 다입니다🎜rrreee🎜커스텀 페이징 구성 요소 교체🎜rrreee🎜프로젝트에서 정적 페이징 구성 요소 사용🎜rrreee

위 내용은 Laravel 프로젝트 의사 정적 페이징 처리 정보의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:learnku.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿