Laravel9.x 对取出指定条数的数据进行分页

作者: 温新

分类: 【Laravel】

阅读: 2906

时间: 2022-03-05 02:16:01

hi,我是温新,一名PHPer

保持着探索,向前方走去。

1.需求

不使用Laravel的paginate进行分页。取出指定条数的数据并对其进行分页。如用户表取出指定的1000条数据,并对这1000条数据进行分页。

2.指定条数的数据进行分页错误案例

1)对于分页,一般是如下操作:

$users = User::paginate(1000);

需要明白的是,这样的写法是对总数据进行分页,并不是对这取出的1000条数据进行分页。

2)对指定条数的数据进行分页的错误写法

$users = User::limit(1000)->paginate(10);

这个错误的案例想表达的是,limit取出1000条数据,然后使用paginate对这1000数据分为10页。Laravel并没有提供这种方法,因此,这种写法是错误的。

解决方法:使用Laravel提供的自定义分页类进行对指定数据进行分页。

3.array_slice()数组方式-代码实现

1)准备路由

<?php
// web.php
Route::get('users', [\App\Http\Controllers\DemoController::class, 'index']);

2)创建控制器并定义方法

<?php
    
namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

class DemoController extends Controller
{
    public function index(Request $request)
    {
        // 获取1000条数据
        $users = User::limit(1000)->get()->toArray();
        // 页码
        $page = $request->page ?? 1;
        //每页的条数
        $perPage = 100;
        //计算每页分页的初始位置
        $offset = ($page * $perPage) - $perPage;
        // 使用自定义分页类实现对指定数据分页
        $users =new LengthAwarePaginator(array_slice($users, $offset, $perPage, true), count($users), $perPage,$page, ['path' => $request->url(), 'query' => $request->query()]);

        return $users;
    }
}

3)路由访问并查看结果

{
    "current_page": 1,
    "data": [
        {
        "id": 1,
        "name": "Dr. Torrey Auer Jr.",
        "email": "romaine61@example.com",
        "email_verified_at": "2022-03-04T14:35:27.000000Z",
        "created_at": "2022-03-04T14:35:27.000000Z",
        "updated_at": "2022-03-04T14:35:27.000000Z"
        }
    ],
    "next_page_url": "http://la8api.test/uesrs?page=2",
    "path": "http://la8api.test/uesrs",
    "per_page": 100,
    "prev_page_url": null,
    "to": 100,
    "total": 1000
}

通过结果可以看到:

total:1000有1000条数据;

per_page:100每页显示100条数据;

4)使用API 资源返回数据

创建资源

php artisan make:resource UserResource

修改资源类

<?php
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    public function toArray($request)
    {
        return [
           'id'   =>  $this['id'],
           'name' =>  $this->resource['name']
        ];
    }
}

修改控制器

<?php
namespace App\Http\Controllers;

use App\Http\Resources\UserResource;

class DemoController extends Controller
{
    public function index(Request $request)
    {
        // 省略了上面的代码
        return UserResource::collection($users);
    }
}

这种方式有个缺点,就是数据集合需要转成数组,如果是数组形式进行分页,配合资源使用时,并不好用。

4.集合方法slice()对象方式-代码实现

基于上面的案例来改动实现。

1)修改控制器方法

<?php

namespace App\Http\Controllers;

use App\Http\Resources\UserResource;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

class DemoController extends Controller
{
    public function index(Request $request)
    {
        // users数据集合对象
        $users = User::limit(1000)->get();
        // 页码
        $page = $request->page ?? 1;
        //每页的条数
        $perPage = 100;
        //计算每页分页的初始位置
        $offset = ($page * $perPage) - $perPage;
        // slice方法对对象进行分页
        $users =new LengthAwarePaginator($users->slice($offset, $perPage), count($users), $perPage,$page, ['path' => $request->url(), 'query' => $request->query()]);

        return UserResource::collection($users);
    }
}

2)修改资源类

<?php
namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    public function toArray($request)
    {
        return [
           'id' =>  $this->id,
           'name' =>  $this->name,
        ];
    }
}

这样完成了数据集合对象的自定义分页。

3)使用场景:对数据集合对象进行自定义分页

请登录后再评论