laravel collection 扩展分页 LengthAwarePaginator 返回json不是数组

0 问题复现

常见的collection分页扩展代码如下所示

//AppServiceProvider 添加如下代码
if (!Collection::hasMacro('paginate')) {
      Collection::macro('paginate',
            function ($perPage = 15, $page = null, $options = []) {
                    $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
                   
                    return (new LengthAwarePaginator(
                        $this->forPage($page, $perPage),
                        $this->count(),
                        $perPage,
                        $page,
                        $options))
                        ->withPath('');
                });
}

但是会遇到一个问题,测试代码:

$collection = collect([1,2,3,4,5,6]);
// 获取第一页数据
"data": {
        "current_page": 1,
        "data": [
            1,
            2,
            3
        ],
        "first_page_url": "?page=1",
        "from": 1,
        "last_page": 2,
        "last_page_url": "?page=2",
        "next_page_url": "?page=2",
        "path": "",
        "per_page": "3",
        "prev_page_url": null,
        "to": 3,
        "total": 6
    }
// 获取第二页数据如下(每页3个元素)
"data": {
        "current_page": 2,
        "data": {
            "3": 4,
            "4": 5,
            "5": 6
        },
        "first_page_url": "?page=1",
        "from": 4,
        "last_page": 2,
        "last_page_url": "?page=2",
        "next_page_url": null,
        "path": "",
        "per_page": "3",
        "prev_page_url": "?page=1",
        "to": 6,
        "total": 6
    }

可以看到,第二页的data数据返回的是json对象,而不是数组,这并不是我们想要的结果

1.原因

https://stackoverflow.com/questions/38712364/laravel-5-lengthawarepaginator-returned-json-not-array
The problem is that the ids remain the keys of your array when array_slice-ing. But since some keys are missing, especially 0, 1, 2, … the array is henceforth treated as associative (['key1'=>'value1', 'key2'=>'value2', …]) rather than numerically indexed (['value1', 'value2', …]) when encoding to json.

当调用array_slice时,id 仍然是数组的键值。当一些键值,比如0,1,2这些缺失,此后将数组编码为json时这些数组会被当成字符串键值关联(['key1'=>'value1', 'key2'=>'value2', …])而不是数字键值关联 (['value1', 'value2', …])

2.解决方法

修改分页方法

In case your $arrayOfData is an Eloquent/Illuminate Collection, 
you can use the methods ->slice($offset, $pageSize)->values() on it. Looks nicer!
// 新的分页扩展
if (!Collection::hasMacro('paginate')) {
            Collection::macro('paginate',
                function ($perPage = 15, $page = null, $options = []) {
                    $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);
                    $offset = ($page * $perPage) - $perPage;
                    return (new LengthAwarePaginator(
//                        $this->forPage($page, $perPage),
                        $this->slice($offset,$perPage)->values(),//使用collect的slice方法,并且获取values来进行赋值
                        $this->count(),
                        $perPage,
                        $page,
                        $options))
                        ->withPath('');
                });
        }

你可能感兴趣的:(laravel collection 扩展分页 LengthAwarePaginator 返回json不是数组)