我如何对 laravel 集合进行分页?

Posted

技术标签:

【中文标题】我如何对 laravel 集合进行分页?【英文标题】:How can i paginate laravel collection? 【发布时间】:2021-04-18 23:17:36 【问题描述】:

这是我尝试分页的方式:

$posts = Post::all()->sortByDesc("created_at")->pagination(1);

但我收到此错误:

方法 Illuminate\Database\Eloquent\Collection::pagination 不存在。

【问题讨论】:

如果这是您真正需要的结果,那就是 Post::latest()->paginate(1) 无需将所有记录加载到集合中然后返回其中的 1 个 这能回答你的问题吗? How can I paginate a merged collection in Laravel 5? 【参考方案1】:

创建帮助类

<?php

namespace App\Helpers;

use Illuminate\Container\Container;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;

class PaginationHelper

    public static function paginate(Collection $results, $showPerPage)
    
        $pageNumber = Paginator::resolveCurrentPage('page');
        
        $totalPageNumber = $results->count();

        return self::paginator($results->forPage($pageNumber, $showPerPage), $totalPageNumber, $showPerPage, $pageNumber, [
            'path' => Paginator::resolveCurrentPath(),
            'pageName' => 'page',
        ]);

    

    /**
     * Create a new length-aware paginator instance.
     *
     * @param  \Illuminate\Support\Collection  $items
     * @param  int  $total
     * @param  int  $perPage
     * @param  int  $currentPage
     * @param  array  $options
     * @return \Illuminate\Pagination\LengthAwarePaginator
     */
    protected static function paginator($items, $total, $perPage, $currentPage, $options)
    
        return Container::getInstance()->makeWith(LengthAwarePaginator::class, compact(
            'items', 'total', 'perPage', 'currentPage', 'options'
        ));
    

在想要添加帮助文件后打开 composer.json 文件,composer 有一个 files 键(这是一个文件路径数组),您可以在 autoload 中定义它

"autoload": 
    "files": [
        "app/Helpers/PaginationHelper.php"
    ],
    "classmap": [
        "database/seeds",
        "database/factories"
    ],
    "psr-4": 
        "App\\": "app/"
    
,

现在你必须在终端中输入这个命令

composer dump-autoload

现在您可以创建一个集合的分页,如下例所示

Route::get('/test_collect_pagintae', function () 

    $users = \App\User::get();

    $showPerPage = 20;

    $paginated = PaginationHelper::paginate($users, $showPerPage);

    return $paginated;
);

【讨论】:

这是我见过的最清晰的 LengthAware 助手实现示例。请问$options是什么,怎么用? 这很漂亮【参考方案2】:

这是因为paginateBuilder 方法,而不是集合。

您需要手动创建分页器,这里如何描述 - https://laravel.com/docs/8.x/pagination#manually-creating-a-paginator

【讨论】:

【参考方案3】:

您可以在方法启动中的 app/provider/serviceProvider 中使用此代码

Collection::macro('paginate', function($perPage, $total = null, $page = null, $pageName = 'page') 
            $page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);
            return new LengthAwarePaginator(
                $this->forPage($page, $perPage),
                $total ?: $this->count(),
                $perPage,
                $page,
                [
                    'path' => LengthAwarePaginator::resolveCurrentPath(),
                    'pageName' => $pageName,
                ]
            );
        );

【讨论】:

【参考方案4】:

试试这个代码:


//convert to array
$posts = Post::all()->sortByDesc("created_at")->toArray();

//Create new pagination
$currentPage = LengthAwarePaginator::resolveCurrentPage();
$perPage = 3;
$currentItems = array_slice($posts, $perPage * ($currentPage - 1), $perPage);
//with path of current page
$posts = (new LengthAwarePaginator($currentItems, count($posts ), $perPage, $currentPage))->setPath(route('posts....'));

//Convert array of array to array of object
$posts->each(function ($item, $itemKey) use($posts) 
     $posts[$itemKey] = (Object)$item;
);

【讨论】:

以上是关于我如何对 laravel 集合进行分页?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.3 对 sortBy 集合进行分页

Laravel 分页不适用于数组而不是集合

如何在 laravel 的分页集合中使用变换

如何在laravel中对相关模型进行分页

我想自学laraver,请诸位前辈给一些建议,谢谢

如何在 laravel&Vue 中对数据进行分页?