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('');
});
}