Разбиение на страницы Laravel для API

Я хочу сделать простую разбивку на страницы для API, используя Laravel в ответе формата, например:

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

как этого добиться? Мне не нравится функция Laravel Model::paginate().

Если вам нужен собственный формат, вы можете использовать красноречивые ресурсы

user3532758 09.05.2022 05:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
1
41
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете начать с создания вспомогательного класса:

<?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;
    }

}

Это всего лишь вспомогательная функция, и я создал ее, потому что почти во всех случаях могут передаваться одни и те же метаданные, так что таким образом я мог хранить все эти данные в одной переменной.

Теперь на контроллере сделайте что-то вроде этого:

//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 [
    'code'          => 0,
    'message'       => 'Success',
    'data'          => $results,
    'page_context'  => [
        'page'           => $meta['page'],
        'per_page'       => $meta['perPage'],
        'has_more_page'  => ($meta['totalPage'] === $meta['page'])?false:true,
    ]
];

Ничего себе, очень простой ответ, и вы даете дополнительную функцию для обработки запроса. Благодарю.

Donny Akhmad Septa Utama 09.05.2022 06:08

Другие вопросы по теме