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,
]
];
我想在格式响应中使用 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,
]
];