mav3rick177/rapid-pagination

此包已被废弃且不再维护。未建议替代包。

Laravel 的快速分页

v0.0.993 2021-05-06 14:29 UTC

This package is auto-updated.

Last update: 2022-12-06 23:35:15 UTC


README

Build Status Coverage Status Scrutinizer Code Quality

Laravel 的快速分页

不使用 OFFSET 的快速分页

要求

  • PHP: ^7.1
  • Laravel: ^5.5 || ^6.0 || ^7.0 || ^8.0

安装

composer require mav3rick177/rapid-pagination

注册服务提供者。

config/app.php:

        /*
         * Package Service Providers...
         */
        mav3rick177\RapidPagination\MacroServiceProvider::class,

基本用法 1

用户表的基本分页

创建路由

Route::post('/users', [UserController::class, 'index'])->name('users.list');
Route::get('/users', [UserController::class, 'index'])->name('users.list');

控制器

init_paginator_cache($fields) 接收表单字段名称列表,并返回一个包含键值对的数组,此缓存用于在页面之间保存表单值!

class UserController extends Controller
{
    ...
    public function index()
    {
        // Form field names
        $formFields = ['sort', 'perPage', 'from', 'to', 'cursor']; 

        // Cache Form values
        $cache = init_rapid_paginator_cache($formFields);
        
        // Extract values from the cache 
        $sort = isset($cache['sort']) ? $cache['sort'] : '>';
        $perPage = isset($cache['perPage']) ? $cache['perPage'] : 10;
        $from = isset($cache['from']) ? $cache['from'] : null;
        $to = isset($cache['to']) ? $cache['to'] : null;
        $field = isset($cache['cursor']) ? $cache['cursor'] : 'id';

        // Columns
        $columns = ['id','name','email', 'dob']; 

        // field to use as a cursor
        $cursor = $field; 

        /*
        ** Query
        */

        $query = User::select($columns);
                   // ->where('email', 'like', '%example.net%');
       
        //Get Users Where Birth Date of Birth is between $from and $to 
        if($cursor == 'dob' && $from != null && $to != null)
            $query = $query->whereBetween('dob', [$from, $to]);
        

        // Call our custom paginator here...
        $result = rapid_paginator($query, $field, $cache, $sort, $perPage);
        
        // return the results
        return view('users')->with($result);
    }
    ...

rapid_paginator() 返回包含两个条目的数组

  • 'items': 包含模型对象以及其他信息的 Rapid Paginator 对象,例如游标以及一些布尔值以检查在当前 '状态' 中是否可以导航到上一页或下一页...在我们的示例中,我们用它来迭代以获取用户列表(在页面中),也将其他信息编码在 '状态' 中
  • 'cache': 包含表单值...

渲染分页

在视图中添加

{{ $items->render() }}

其中 $items 是 Rapid Paginator 对象...

基本用法 2

然后您可以从查询构建器、Eloquent 构建器和关系链式调用 ->rapid_pagination() 方法。

$cursor = [
    'id' => 3,
    'created_at' => '2017-01-10 00:00:00',
    'updated_at' => '2017-01-20 00:00:00',
];

$result = App\Post::whereUserId(1)
    ->rapid_pagination()
    ->forward()
    ->limit(5)
    ->orderByDesc('updated_at') // ORDER BY `updated_at` DESC, `created_at` DESC, `id` DESC
    ->orderByDesc('created_at')
    ->orderByDesc('id')
    ->seekable()
    ->paginate($cursor)
    ->toJson(JSON_PRETTY_PRINT);

它将运行优化后的查询。

(

    SELECT * FROM `posts`
    WHERE `user_id` = 1
    AND (
        `updated_at` = '2017-01-20 00:00:00' AND `created_at` = '2017-01-10 00:00:00' AND `id` > 3
        OR
        `updated_at` = '2017-01-20 00:00:00' AND `created_at` > '2017-01-10 00:00:00'
        OR
        `updated_at` > '2017-01-20 00:00:00'
    )
    ORDER BY `updated_at` ASC, `created_at` ASC, `id` ASC
    LIMIT 1

) UNION ALL (

    SELECT * FROM `posts`
    WHERE `user_id` = 1
    AND (
        `updated_at` = '2017-01-20 00:00:00' AND `created_at` = '2017-01-10 00:00:00' AND `id` <= 3
        OR
        `updated_at` = '2017-01-20 00:00:00' AND `created_at` < '2017-01-10 00:00:00'
        OR
        `updated_at` < '2017-01-20 00:00:00'
    )
    ORDER BY `updated_at` DESC, `created_at` DESC, `id` DESC
    LIMIT 6

)

然后您将获得

{
  "records": [
    {
      "id": 3,
      "user_id": 1,
      "text": "foo",
      "created_at": "2017-01-10 00:00:00",
      "updated_at": "2017-01-20 00:00:00"
    },
    {
      "id": 5,
      "user_id": 1,
      "text": "bar",
      "created_at": "2017-01-05 00:00:00",
      "updated_at": "2017-01-20 00:00:00"
    },
    {
      "id": 4,
      "user_id": 1,
      "text": "baz",
      "created_at": "2017-01-05 00:00:00",
      "updated_at": "2017-01-20 00:00:00"
    },
    {
      "id": 2,
      "user_id": 1,
      "text": "qux",
      "created_at": "2017-01-17 00:00:00",
      "updated_at": "2017-01-18 00:00:00"
    },
    {
      "id": 1,
      "user_id": 1,
      "text": "quux",
      "created_at": "2017-01-16 00:00:00",
      "updated_at": "2017-01-18 00:00:00"
    }
  ],
  "has_previous": false,
  "previous_cursor": null,
  "has_next": true,
  "next_cursor": {
    "updated_at": "2017-01-18 00:00:00",
    "created_at": "2017-01-14 00:00:00",
    "id": 6
  }
}

资源集合

Rapid Pagination 支持 Laravel 的 API 资源。

在资源及其资源集合上使用辅助特性。

use Illuminate\Http\Resources\Json\JsonResource;
use mav3rick177\RapidPagination\RapidPaginationResourceTrait;

class PostResource extends JsonResource
{
    use RapidPaginationResourceTrait;
}
use Illuminate\Http\Resources\Json\ResourceCollection;
use mav3rick177\RapidPagination\RapidPaginationResourceCollectionTrait;

class PostResourceCollection extends ResourceCollection
{
    use RapidPaginationResourceCollectionTrait;
}
$posts = App\Post::rapid_pagination()
    ->orderByDesc('id')
    ->paginate();

return new PostResourceCollection($posts);
{
  "data": [/* ... */],
  "has_previous": false,
  "previous_cursor": null,
  "has_next": true,
  "next_cursor": {/* ... */}
}

名称 类型 父类 描述
mav3rick177\RapidPagination\Paginator mav3rick177\RapidPagination\Base\Paginator Laravel 的流畅工厂实现
mav3rick177\RapidPagination\Processor mav3rick177\RapidPagination\Base\AbstractProcessor Laravel 的处理器实现
mav3rick177\RapidPagination\PaginationResult mav3rick177\RapidPagination\Base\PaginationResult Laravel 的分页结果实现
mav3rick177\RapidPagination\MacroServiceProvider Illuminate\Support\ServiceProvider 启用从查询构建器、Eloquent 构建器和关系链式可调用的宏
mav3rick177\RapidPagination\RapidPaginationResourceTrait 特性 支持 Laravel JsonResource
mav3rick177\RapidPagination\RapidPaginationResourceCollectionTrait 特性 支持Laravel ResourceCollection

PaginatorProcessorPaginationResult均可进行宏定义。

API

Paginator::__construct()
Paginator::create()

创建一个新的分页实例。
然而,如果您使用Laravel宏,则无需直接实例化。

static Paginator create(QueryBuilder|EloquentBuilder|Relation $builder): static
Paginator::__construct(QueryBuilder|EloquentBuilder|Relation $builder)
  • QueryBuilder表示\Illuminate\Database\Query\Builder
  • EloquentBuilder表示\Illuminate\Database\Eloquent\Builder
  • Relation表示\Illuminate\Database\Eloquent\Relation

Paginator::transform()

将RapidPagination查询转换为Illuminate构建器。

Paginator::transform(Query $query): QueryBuilder|EloquentBuilder|Relation

Paginator::build()

执行配置+转换。

Paginator::build(\mav3rick177\RapidPagination\Base\Contracts\Cursor|array $cursor = []): QueryBuilder|EloquentBuilder|Relation

Paginator::paginate()

执行配置+转换+处理。

Paginator::paginate(\mav3rick177\RapidPagination\Base\Cursor|array $cursor = []): \mav3rick177\RapidPagination\PaginationResult

参数

  • (mixed) $cursor
    包含$column => $value的关联数组或实现\mav3rick177\RapidPagination\Base\Contracts\Cursor的对象。它必须是**全部或无**。
    • 对于初始页面,省略此参数或传递空数组。
    • 对于后续页面,传递所有参数。不允许部分参数。

返回值

例如。

(使用\Illuminate\Database\Eloquent\Builder时的默认格式)

object(mav3rick177\RapidPagination\PaginationResult)#1 (5) {
  ["records"]=>
  object(Illuminate\Database\Eloquent\Collection)#2 (1) {
    ["items":protected]=>
    array(5) {
      [0]=>
      object(App\Post)#2 (26) { ... }
      [1]=>
      object(App\Post)#3 (26) { ... }
      [2]=>
      object(App\Post)#4 (26) { ... }
      [3]=>
      object(App\Post)#5 (26) { ... }
      [4]=>
      object(App\Post)#6 (26) { ... }
    }
  }
  ["hasPrevious"]=>
  bool(false)
  ["previousCursor"]=>
  NULL
  ["hasNext"]=>
  bool(true)
  ["nextCursor"]=>
  array(2) {
    ["updated_at"]=>
    string(19) "2017-01-18 00:00:00"
    ["created_at"]=>
    string(19) "2017-01-14 00:00:00"
    ["id"]=>
    int(6)
  }
}

Paginator::useFormatter()
Paginator::restoreFormatter()
Paginator::process()

调用处理器方法。

Paginator::useFormatter(Formatter|callable $formatter): $this
Paginator::restoreFormatter(): $this
Paginator::process(\mav3rick177\RapidPagination\Base\Query $query, \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Collection $rows): \mav3rick177\RapidPagination\PaginationResult

PaginationResult::toArray()
PaginationResult::jsonSerialize()

将对象转换为数组。

重要提示:属性名从camelCase转换为snake_case形式。

PaginationResult::toArray(): array
PaginationResult::jsonSerialize(): array

PaginationResult::__call()

调用宏或集合方法。

PaginationResult::__call(string $name, array $args): mixed

例如。

PaginationResult::macro('foo', function () {
    return ...;
});
$foo = $result->foo();
$first = $result->first();

注意:这是一个lampager修改

lampager/lampager
lampager/lampager-laravel