ホームページ >PHPフレームワーク >Laravel >Laravelプロジェクトの擬似静的ページング処理について

Laravelプロジェクトの擬似静的ページング処理について

藏色散人
藏色散人転載
2021-02-20 17:27:273295ブラウズ

次は、Laravel プロジェクト疑似プロジェクトを紹介する Laravel チュートリアルコラムです。 -静的ページング処理。困っている友達のお役に立てれば幸いです。

疑似静的処理を必要とする Laravel プロジェクトがあります。このプロジェクトは、Laravel 独自のページング コンポーネントを使用しています。ページング コンポーネントは、クエリを使用して URL 内のページ番号を渡します。疑似条件を満たすことができません。 -静的要件。

望ましい効果

擬似静的に望む効果はおおよそ次のとおりです:

 /software/3dmax/created_at/page-1.html

Laravel に対応するルートは次のとおりです:

/software/{category}/{order}/page-{page}.html

Laravel ルーティング自体がルーティングパラメータをサポートしているため、変数の取得に問題はありませんが、Laravel 独自のページングコンポーネントは Query を使用してパラメータを渡すため、生成されるページングアドレスは次のようになります Kind of

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

Thisは必要なものではないため、Laravel 独自のページングコンポーネントを変更する必要があります。

Laravel ページネーション コンポーネント

Laravel では、ページネーションが必要な場合、モデル内で paginate メソッドを呼び出し、各ページのページ番号を渡します。

  • paginate メソッドは、Illuminate\Database\Concerns\BuildsQueries にある paginator メソッドを呼び出します。
  • paginator メソッドは、Illuminate\Pagination\LengthAwarePaginator のインスタンスを構築します。
  • Illuminate\Pagination\LengthAwarePaginator は、Illuminate\Pagination\AbstractPaginatorurl メソッドを使用して、リクエスト パラメーターと URL を構築します。

URL が生成される場所が見つかったので、ここで行う必要があるのはそれを変更することだけです。

ページングコンポーネントを書き直す

Laravel 自体はカスタムページングコンポーネントをサポートしていますが、私たちがやっていることはカスタムページングではないため、メソッドを書き直す必要があります。

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

Rewrite Url メソッド

まず、Laravel 自身のページングは​​、ルート内のパラメータをクエリに入力します。必要なのはパラメータ、またはアドレスにパラメータを入力することです。

  • すべてのクエリパラメータを取得します
  • ページルートにページ分割が必要なバインドされたルーティングパラメータがあるかどうかを判断します
  • そうでない場合は、Laravel 自体のページングを使用します
  • 存在する場合は、ルーティングとルーティング パラメーターを通じてアドレスを構築し、クエリ パラメーターから削除します
  • 現在のクエリ パラメーターにパラメーターがあるかどうかを判断します。私たちは以前と同じです。

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 で定義されています。書き直す必要がある場合は、非常に難しくなります。もう 1 つの問題は、ページングのすべてが擬似静的である必要があるわけではないことです。たとえば、ユーザー センターのデータは擬似静的である必要がない可能性があります。したがって、手動で設定できるものが必要です。Larave モデルにはローカル スコープがあります。メソッド staticPaginate を作成できます。静的ページネーションを使用する必要がある場合は、Model-> を使用できます。 query ()->staticPaginate(); を呼び出すために必要なパラメータは、Laravel に付属する pageinage メソッドと似ています。

パブリックモデル基本クラスファイル

通常、Laravelプロジェクトではモデルを直接継承しませんIlluminate\Database\Eloquent\Model 通常はappを使用します。 \Models ディレクトリは Model 基本クラスを定義します。すべてのモデルは Model 基本クラスから継承します。これは必須ではありませんが、モデルを変更するかパブリック メソッドを追加すると便利です。

モデル内のローカル スコープを定義します

paginate メソッドの内容を Illuminate\Database\Eloquent\Builder にコピーするだけです。 $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プロジェクトの擬似静的ページング処理についての詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlearnku.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。