germania-kg / pagination
分页你的可遍历对象
Requires
- php: ^7.0
- psr/http-message: ^1.0
Requires (Dev)
- guzzlehttp/psr7: ^1.5
- php-coveralls/php-coveralls: ^2.0
- phpunit/phpunit: ^5.7|^6.0|^7.0
This package is auto-updated.
Last update: 2024-08-29 04:54:43 UTC
README
使用Composer安装
$ composer require germania-kg/pagination
概览
分页:简单的分页!支持当前页、下一页、上一页、第一页和最后一页页码,以及总页数和可自定义的每页大小。
PaginationFactory:用于创建Pagination实例的可调用类。与$_GET['page']
配合使用效果极佳
PaginationIterator:根据Pagination状态限制你的可遍历对象。对于分页的JSON API资源非常有用。
JsonApiPaginationDecorator:为你的JSON API资源集合创建有用的links
和meta
信息。
用法
Pagination 类
只需传递要分页的项目数量。默认页大小为25, Pagination类将计算页码。下面有自定义示例。
<?hpp use Germania\Pagination\Pagination; $items_count = 100; // count( $things ) or integer; $pagination = new Pagination( $items_count ); $pagination->getPagesCount(); // 4, with 25 items each $pagination->getFirst(); // 0 $pagination->getLast(); // 3
分页状态
在实例化后,用户没有选择任何页面。因此,Pagination被认为是非活动状态。
请注意,当前页也可能为int(0)
- 第一页。这就是为什么我们必须检查null
的原因。 isActive方法是一个方便的别名,即$p->getCurrent() === null
。
$pagination->isActive(); // FALSE $pagination->getCurrent(); // null $pagination->getPrevious(); // null $pagination->getNext(); // null
它首先需要调用setCurrent来变为活动状态
设置当前页
use Germania\Pagination\PaginationRangeException; try { $pagination->setCurrent( 1 ); $pagination->isActive(); // TRUE $pagination->getCurrent(); // 1 $pagination->getPrevious(); // null $pagination->getNext(); // 2 } catch ( PaginationRangeException $e ) { echo $e->getMessage(); // "Invalid Page number" echo $e->getCode(); // 400 }
设置页大小
虽然默认每页项目数为25,但你可以设置另一个大小——默认为100
use Germania\Pagination\PaginationRangeException; try { $pagination = new Pagination( $items_count ); $pagination->getPageSize(); // 25 $pagination->setPageSize( 999 ); } catch ( PaginationRangeException $e ) { echo $e->getMessage(); // "Invalid Page size (max. 100)" echo $e->getCode(); // 400 }
通过构造函数参数调整页大小
$custom_page_size = 50; // default: 25 $pagination = new Pagination( $items_count, $custom_page_size ); $max_page_size = 200; // default: 100 $pagination = new Pagination( $items_count, $custom_page_size, $max_page_size );
PaginationFactory
PaginationFactory的构造函数还接受Countable
、Traversable
或arrays
的实例,因此你不需要自己计数项目。第二个参数可以是页码整数或包含number
和/或size
值的数组。
<?php use Germania\Pagination\PaginationFactory; // Optinally set default page size $factory = new PaginationFactory; $factory = new PaginationFactory( 25 ); // Most simple: just integers $items_count = 65; $choose_page = 2; // Create Pagination instance: $pagination = $factory( $items_count, $choose_page );
从数组创建在处理查询参数(如$_GET['page']
)时非常有用
// Both elements are optional. $pagination = $factory( $items_count, [ 'number' => 2, // default: 0 'size' => 20 ]); // User Input $pagination = $factory( $items_count, $_GET['page'] ?? [] );
PaginationIterator
根据分页状态将任何\Traversable
迭代器限制为当前页大小。 PaginationIterator的构造函数接受你的迭代器和你的分页实例。它也是\Countable
,可以计算当前页显示的项目数量。
<?php use Germania\Pagination\PaginationIterator; // Have your pagination at hand... $pagination = ... $pagination->setCurrent(2); // Setup something really big $collection = new MyHugeIterator( $thousand_items ); $paginated_collection = new PaginationIterator( $collection, $pagination ); echo count( $paginated_collection ); // 25 foreach( $paginated_collection as $item): // loop: 25 items on page 2 endforeach;
使用哪个迭代器?
根据分页状态,在foreach循环中使用的PaginationIterator的内部迭代器是\LimitIterator
还是当分页不是活动状态时MyHugeIterator
实例本身
// this time, we do not pick a page number! $thousand_items = ... $pagination = new Pagination( count($thousand_items) ); $pagination->isActive(); // null $collection = new MyHugeIterator( $thousand_items ); $paginated_collection = new PaginationIterator( $collection, $pagination ); $iterator = $paginated_collection->getIterator(); get_class( $iterator ); // MyHugeIterator instance
JsonApiPaginationDecorator
这个库提供了一个方便的JsonApiPaginationDecorator,它将使用给定的\Psr\Http\Message\UriInterface实例生成有用的信息,用于你的JSON API资源集合响应。
支持元信息
可以使用meta
成员包含非标准元信息,如我们的分页
$pagination->setCurrent( 16 ); $pagination->setPageSize( 10 ); $links = $ja_decorator->getMeta(); // array( // numberOfPages => 23 // currentPage => 16 // pageSize => 10 // )
当分页不是活动状态时,结果数组将为空。
支持链接对象
在 fetching pagination 部分的 JSON API specs 提议使用 page[number]
和 page[size]
来自定义分页输出。并且它指出,在使用分页链接时,集合中的 links
对象必须使用这些键名。
first
:数据的第一个页面last
:数据的最后一个页面prev
:前一个数据页面next
:下一个数据页面
JsonApiPaginationDecorator 为您生成这些元素。这个类也是 \JsonSerializable
。
<?php use Germania\Pagination\JsonApiPaginationDecorator; // Prepare dependencies $uri = \GuzzleHttp\Psr7\uri_for('http://example.com'); $pagination = ... $pagination->setCurrent( 2 ); new $ja_decorator = new JsonApiPaginationDecorator( $pagination, $uri); // These are equivalent: $links = $ja_decorator->getLinks(); $links = $ja_decorator->jsonSerialize(); // array( // first => http://example.com/?page[number]=0 // last => http://example.com/?page[number]=42 // previous => http://example.com/?page[number]=1 // next => http://example.com/?page[number]=3 // )
默认查询参数
JsonApiPaginationDecorator 在内部会调用 PSR-7 $uri 实例的 withQuery 方法。不幸的是,这将会替换 URI 中包含的任何查询参数。只需将需要的查询参数作为第三个构造函数参数传递即可。
$params = array( 'foo' => 'bar', 'json' => 'cool' ); new $ja_decorator = new JsonApiPaginationDecorator( $pagination, $uri, $params); $links = $ja_decorator->getLinks(); // array( // first => http://example.com/?page[number]=0&foo=bar&json=cool // last => http://example.com/?page[number]=42&foo=bar&json=cool // previous => http://example.com/?page[number]=1&foo=bar&json=cool // next => http://example.com/?page[number]=3&foo=bar&json=cool // )
自定义页面大小
如果您设置了自定义的页面大小(与默认大小不同),链接将获得一个额外的 size
字段。
$pagination->setPageSize( 10 ); $links = $ja_decorator->getLinks(); // array( // first => http://example.com/?page[number]=0&page[size]=10 // last => http://example.com/?page[number]=42&page[size]=10 // previous => http://example.com/?page[number]=1&page[size]=10 // next => http://example.com/?page[number]=3&page[size]=10 // )
边缘情况
在第一页和最后一页,previous
和 next
链接没有意义。它们的值将是 null。
$pagination = new Pagination (...); new $ja_decorator = new JsonApiPaginationDecorator( $pagination, $uri); $pagination->setCurrent( 0 ); $links = $ja_decorator->getLinks(); // array( // ... // previous => null // next => http://example.com/?page[number]=1 // ) $pagination->setCurrent( 42 ); $links = $ja_decorator->getLinks(); // array( // ... // previous => http://example.com/?page[number]=41 // next => null // )
当分页不活跃时,所有默认值都是 null。
$pagination = new Pagination (...); $pagination->isActive(); // FALSE $ja_decorator->getLinks(); // array( // first => null // last => null // previous => null // next => null // )
过滤结果
为了得到一个干净、整洁的 links
数组,您可以将一个布尔值 filter 标志作为第四个构造函数参数传递。
$filter = true; new $ja_decorator = new JsonApiPaginationDecorator( $pagination, $uri, [], $filter); $ja_decorator->getLinks(); // array()
问题
请参阅 完整问题列表。
开发
$ git clone https://github.com/GermaniaKG/Pagination.git
$ cd Pagination
$ composer install
单元测试
您可以选择将 phpunit.xml.dist
复制到 phpunit.xml
并根据您的需求进行适配,或者保持原样。运行 PhpUnit 测试或 composer 脚本,如下所示
$ composer test # or $ vendor/bin/phpunit