Laravel API 分页

Laravel pagination for API

我想在格式响应中使用 Laravel 为 API 进行简单的分页,如下所示:

{
    "code": 0,
    "message": "success",
    "data": [
        {...},
        {...}
    ],
    "page_context": {
        "page": 2,
        "per_page": 25,
        "has_more_page": false
    }
}

如何实现?我不喜欢 Laravel Model::paginate() 函数。

您可以先创建一个助手 class:

<?php

namespace App\Helpers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;

class AppHelper
{
    public static function defaultMetaInput($input) : array
    {
        $page = isset($input['page']) ? (int)$input['page'] : 1;
        $perPage = isset($input['perPage']) ? (int)$input['perPage'] : 50;
        $order = $input['order'] ?? 'created_at';
        $dir = $input['dir'] ?? 'desc';
        $search = isset($input['search']) ? ($input['search']) : '';
        $offset = ($page - 1) * $perPage;
        return [
            'order'     => $order,
            'dir'       => $dir,
            'page'      => $page,
            'perPage'   => $perPage,
            'offset'    => $offset,
            'search'    => $search,
        ];
    }

    public static function additionalMeta($meta, $total)
    {
        $meta['total'] = $total;
        $meta['totalPage'] = ceil( $total / $meta['perPage']);
        if($meta['totalPage'] < $meta['page']){
            $meta['page'] = $meta['totalPage'];
        }
        return $meta;
    }

}

这只是一个辅助函数,我创建了它,因为在几乎每个 crud 上,可能会传递相同的元数据,所以这样我就可以将所有这些数据放在一个变量中。

现在,在控制器上做这样的事情:

//storing all meta data on a single $meta variable
$meta = AppHelper::defaultMetaInput($request->only(['page', 'perPage', 'order', 'dir','search']));
$query = \DB::table('users as u')
    ->select('u.*');
$query->where(function($q) use($meta){
    $q->orWhere('u.name', 'like', $meta['search'] . '%')
        ->orWhere('u.email', 'like', $meta['search'] . '%');
});

$total = $query->count();

//adding total data on the meta varaible to send on front end,
//so that this data could be used for pagination on front end
$meta = AppHelper::additionalMeta($meta, $total);

$query->orderBy($meta['order'], $meta['dir']);

//if perPage = -, it will returns all data from the table
if ($meta['perPage'] != '-1') {
    $query->offset($meta['offset'])->limit($meta['perPage']);
}
$results = $query->get();
return [
    'results'  => $results,
    'meta'     =>  $meta
];

这是一个示例,您可以根据需要调整数据。我在我的例子中使用了 meta 你可以将它重命名为任何变量,另外,对于你的 has_more_page 变量,你可以检查 $meta['totalPage'] === $meta['page'] 是否没有更多页面。

如果您需要问题中提到的确切结构,您可以 return 这个代替。

return [
    'code'          => 0,
    'message'       => 'Success',
    'data'          => $results,
    'page_context'  => [
        'page'           => $meta['page'],
        'per_page'       => $meta['perPage'],
        'has_more_page'  => ($meta['totalPage'] === $meta['page'])?false:true,
    ]
];