分页¶
概览¶
分页器是一个组件,用于帮助逐步分割大量数据。例如一次显示博客中的5篇文章。Phalcon Paginator 接受参数,并基于这些参数返回相关的片段整个结果集,以便开发人员可以展示分页后的数据。
<?php
declare(strict_types=1);
use Phalcon\Paginator\Adapter\NativeArray;
$currentPage = 2;
$paginator = new NativeArray(
[
"data" => [
["id" => 1, "name" => "Artichoke"],
["id" => 2, "name" => "Carrots"],
["id" => 3, "name" => "Beet"],
["id" => 4, "name" => "Lettuce"],
["id" => 5, "name" => ""],
],
"limit" => 2,
"page" => $currentPage,
]
);
$paginate = $paginator->paginate();
上面的示例使用一个数组作为来源,并将结果限制为每次2条记录。它将返回id为3
和4
的元素,因为page
已设置为2
.
适配器¶
对于数据源,该组件使用适配器。它附带以下适配器:
适配器 | 描述 |
---|---|
Phalcon\分页器\适配器\Model | 使用Phalcon\Mvc\Model\Resultset对象作为源数据。 |
Phalcon\分页器\适配器\NativeArray | 使用 PHP 数组作为源数据 |
Phalcon\分页器\适配器\QueryBuilder | 使用Phalcon\Mvc\Model\Query\Builder对象作为源数据 |
注意
因为 PDO 不支持可滚动游标,Phalcon\分页器\适配器\Model不应该用来分页大量记录
方法¶
每个适配器都需要选项才能正常运行。这些选项在适配器的构造函数中以键/值数组形式传递。
选项 | 描述 |
---|---|
builder | 仅用于Phalcon\分页器\适配器\QueryBuilder来传递构建器对象 |
data | 要分页的数据(Phalcon\分页器\适配器\NativeArray适配器) |
limit (int ) | 页面大小。如果limit 为负数,则会抛出异常。 |
model | 要分页的数据(Phalcon\分页器\适配器\Model适配器) |
page (int ) | 当前页面 |
repository | Phalcon\分页器\RepositoryInterface- 一个设置结果集的仓库对象。关于仓库的更多信息,请见下文。 |
公开的方法包括:
方法 | 描述 |
---|---|
getLimit(): int | 获取当前行数限制 |
getRepository(array $properties = null): RepositoryInterface | 获取当前用于分页的存储库 |
setCurrentPage(int $page): AdapterInterface | 设置当前页码 |
setLimit(int $limitRows): AdapterInterface | 设置当前行数限制 |
setRepository(RepositoryInterface $repository): AdapterInterface | 设置当前用于分页的存储库 |
模型¶
The Phalcon\分页器\适配器\Model适配器使用Phalcon\Mvc\Model\Resultset作为数据源。这是模型上find()
方法的结果。
<?php
declare(strict_types=1);
use MyApp\Models\Invoices;
use Phalcon\Paginator\Adapter\Model;
$currentPage = 2;
$paginator = new Model(
[
"model" => Invoices::class,
"parameters" => [
"inv_cst_id = :cst_id:",
"bind" => [
"cst_id" => 1
],
"order" => "inv_title"
],
"limit" => 25,
"page" => $currentPage,
]
);
$paginate = $paginator->paginate();
数组接受model
用于要使用的模型类。将在其上调用find()
方法。此外,此适配器还可以接受parameters
作为数组,find()
可以使用包含所有必要条件的数组。
数组¶
The Phalcon\分页器\适配器\NativeArray接受一个PHP数组作为数据源。
<?php
declare(strict_types=1);
use Phalcon\Paginator\Adapter\NativeArray;
$currentPage = 2;
$paginator = new NativeArray(
[
"data" => [
["id" => 1, "name" => "Artichoke"],
["id" => 2, "name" => "Carrots"],
["id" => 3, "name" => "Beet"],
["id" => 4, "name" => "Lettuce"],
["id" => 5, "name" => ""],
],
"limit" => 2,
"page" => $currentPage,
]
);
$paginate = $paginator->paginate();
查询生成器¶
The Phalcon\分页器\适配器\QueryBuilder适配器使用Phalcon\Mvc\Model\Query\Builder对象来对数据库执行 PHQL 查询。
<?php
declare(strict_types=1);
use MyApp\Models\Invoices;
use Phalcon\Paginator\Adapter\QueryBuilder;
$builder = $this
->modelsManager
->createBuilder()
->columns("inv_id, inv_title")
->from(Invoices::class)
->orderBy("inv_title");
$paginator = new QueryBuilder(
[
"builder" => $builder,
"limit" => 20,
"page" => 1,
]
);
$paginate = $paginator->paginate();
仓库¶
The paginate()
方法完成分页数据的所有工作。它返回一个Phalcon\分页器\Repository对象,该对象存储了分页所需的所有必要元素。该对象公开以下常量:
PROPERTY_CURRENT_PAGE
= "current";PROPERTY_FIRST_PAGE
= "first";PROPERTY_ITEMS
= "items";PROPERTY_LAST_PAGE
= "last";PROPERTY_LIMIT
= "limit";PROPERTY_NEXT_PAGE
= "next";PROPERTY_PREVIOUS_PAGE
= "previous";PROPERTY_TOTAL_ITEMS
= "total_items";
方法¶
公开的方法包括:
方法 | 描述 |
---|---|
getAliases(): array | 获取属性存储库的别名 |
getCurrent(): int | 获取当前页码 |
getFirst(): int | 获取首页码 |
getItems(): mixed | 获取当前页上的项目 |
getLast(): int | 获取最后一页码 |
getLimit(): int | 获取当前行数限制 |
getNext(): int | 获取下一页码 |
getPrevious(): int | 获取上一页码 |
getTotalItems(): int | 获取总项目数 |
setAliases(array $aliases): RepositoryInterface | 设置属性存储库的别名 |
setProperties(array $properties): RepositoryInterface | 设置存储库属性的值 |
您可以通过上面的方法访问数据,或者使用定义在常量中的魔法属性:
<?php
use Phalcon\Paginator\Adapter\NativeArray;
$currentPage = 2;
$paginator = new NativeArray(
[
"data" => [
["id" => 1, "name" => "Artichoke"],
["id" => 2, "name" => "Carrots"],
["id" => 3, "name" => "Beet"],
["id" => 4, "name" => "Lettuce"],
["id" => 5, "name" => ""],
],
"limit" => 2,
"page" => $currentPage,
]
);
$paginate = $paginator->paginate();
echo $paginate->getCurrent(); // 2
echo $paginate->current ; // 2
echo $paginate->getFirst(); // 1
echo $paginate->first; // 1
var_dump($paginate->getItems());
// [
// [
// 'id' => 3
// 'name' => "Beet",
// ],
// [
// 'id' => 4,
// 'name' => "Lettuce",
// ]
// ]
var_dump($paginate->getItems());
echo $paginate->getLast(); // 3
echo $paginate->last; // 3
echo $paginate->getLimit(); // 2
echo $paginate->limit; // 2
echo $paginate->getNext(); // 3
echo $paginate->next; // 3
echo $paginate->getPrevious(); // 1
echo $paginate->previous; // 1
echo $paginate->getTotalItems(); // 5
echo $paginate->total_items; // 5
别名¶
如果您希望为仓库对象暴露的每个魔法属性使用自己的名称,可以使用setAliases()
方法实现。
<?php
declare(strict_types=1);
use Phalcon\Paginator\Repository;
use Phalcon\Paginator\Adapter\NativeArray;
$repository = = new Repository();
$repository->setAliases(
[
'myCurrentPage' => $repository::PROPERTY_CURRENT_PAGE,
'myFirstPage' => $repository::PROPERTY_FIRST_PAGE,
'myLastPage' => $repository::PROPERTY_LAST_PAGE,
'myLimit' => $repository::PROPERTY_LIMIT,
'myNextPage' => $repository::PROPERTY_NEXT_PAGE,
'myTotalItems' => $repository::PROPERTY_TOTAL_ITEMS,
]
);
$currentPage = 2;
$paginator = new NativeArray(
[
"data" => [
["id" => 1, "name" => "Artichoke"],
["id" => 2, "name" => "Carrots"],
["id" => 3, "name" => "Beet"],
["id" => 4, "name" => "Lettuce"],
["id" => 5, "name" => ""],
],
"limit" => 2,
"page" => $currentPage,
'repository' => $repository,
]
);
$paginate = $paginator->paginate();
echo $paginate->myCurrentPage; // 2
echo $paginate->myFirstPage; // 1
echo $paginate->myLastPage; // 3
echo $paginate->myLimit; // 2
echo $paginate->myNextPage; // 3
echo $paginate->myTotalItems; // 1
您也可以通过实现Phalcon\分页器\RepositoryInterface接口。
工厂¶
您可以使用分页工厂类实例化一个新的分页器对象。服务的名称为:
名称 | 类 |
---|---|
model | Phalcon\分页器\适配器\Model |
nativeArray | Phalcon\分页器\适配器\NativeArray |
queryBuilder | Phalcon\分页器\适配器\QueryBuilder |
新实例¶
一种可以使用的方法是newInstance()
:
<?php
declare(strict_types=1);
use MyApp\Models\Invoices;
use Phalcon\Paginator\PaginatorFactory;
$builder = $this
->modelsManager
->createBuilder()
->columns('inv_id, inv_title')
->from(Invoices::class)
->orderBy('name')
;
$options = [
'builder' => $builder,
'limit' => 20,
'page' => 1,
];
$factory = new PaginatorFactory();
$paginator = $factory->newInstance('queryBuilder');
加载¶
使用adapter
选项加载分页器适配器类。传入的配置可以是一个数组或一个Phalcon\Config\Config对象,包含类实例化所需的必要条目。
<?php
declare(strict_types=1);
use MyApp\Models\Invoices;
use Phalcon\Paginator\PaginatorFactory;
$builder = $this
->modelsManager
->createBuilder()
->columns('inv_id, inv_title')
->from(Invoices::class)
->orderBy('inv_title')
;
$options = [
'builder' => $builder,
'limit' => 20,
'page' => 1,
'adapter' => 'queryBuilder',
];
$paginator = (new PaginatorFactory())->load($options);
示例配置对象如下:
配置期望一个元素adapter
用于相关适配器和一个options
包含适配器必要选项的数组。
异常¶
Paginator 组件中抛出的任何异常都将属于类型Phalcon\分页器\Exception。你可以使用此异常选择性地捕获仅从此组件抛出的异常。
<?php
use Phalcon\Paginator\Adapter\NativeArray;
use Phalcon\Paginator\Exception;
try {
$currentPage = 2;
$paginator = new NativeArray(
[
"data" => [
["id" => 1, "name" => "Artichoke"],
["id" => 2, "name" => "Carrots"],
["id" => 3, "name" => "Beet"],
["id" => 4, "name" => "Lettuce"],
["id" => 5, "name" => ""],
],
"limit" => -5,
"page" => $currentPage,
]
);
$paginate = $paginator->paginate();
} catch (Exception $ex) {
echo $ex->getMessage();
}
示例¶
在下面的例子中,分页器将使用模型查询结果作为其源数据,并将每页显示数据限制为10条记录:
完整¶
<?php
declare(strict_types=1);
use MyApp\Models\Invoices;
use Phalcon\Http\Request;
use Phalcon\Mvc\Controller;
use Phalcon\Mvc\View;
use Phalcon\Paginator\Adapter\Model as PaginatorModel;
/**
* @property Request $request
* @property View $view
*/
class InvoicesController extends Controller
{
public function listAction()
{
$currentPage = $this->request->getQuery('page', 'int', 1);
$paginator = new PaginatorModel(
[
'model' => Invoices::class,
'limit' => 10,
'page' => $currentPage,
]
);
$page = $paginator->paginate();
$this->view->setVar('page', $page);
}
}
在上面的例子中,$currentPage
包含一个整数,用户提供的变量,表示要显示的页面。而$paginator->paginate()
返回一个Phalcon\分页器\Repository对象,该对象包含分页数据。例如可以在视图中用于生成分页:
<table>
<tr>
<th>Id</th>
<th>Status</th>
<th>Title</th>
</tr>
<?php foreach ($page->getItems() as $item) { ?>
<tr>
<td><?php echo $item['inv_id']; ?></td>
<td><?php echo ($item['inv_status_flag']) ? 'Paid' : ''; ?></td>
<td><?php echo $item['inv_title']; ?></td>
</tr>
<?php } ?>
</table>
The $page
对象还包含导航数据:
<a href="/invoices/list">First</a>
<a href="/invoices/list?page=<?= $page->getPrevious(); ?>">Previous</a>
<a href="/invoices/list?page=<?= $page->getNext(); ?>">Next</a>
<a href="/invoices/list?page=<?= $page->getLast(); ?>">Last</a>
<?php echo "Page {$page->getCurrent()} of {$page->getLast()}"; ?>
工厂¶
您可以使用AdapterFactory
.
模型
<?php
declare(strict_types=1);
use MyApp\Models\Invoices;
use Phalcon\Paginator\PaginatorFactory;
$factory = new PaginatorFactory();
$currentPage = 2;
$options = [
'model' => Invoices::class,
'limit' => 10,
'page' => $currentPage,
];
$paginator = $factory->newInstance('model', $options);
数组
<?php
declare(strict_types=1);
use MyApp\Models\Invoices;
use Phalcon\Paginator\PaginatorFactory;
$factory = new PaginatorFactory();
$currentPage = 2;
$options = [
'data' => [
['id' => 1, 'name' => 'Artichoke'],
['id' => 2, 'name' => 'Carrots'],
['id' => 3, 'name' => 'Beet'],
['id' => 4, 'name' => 'Lettuce'],
['id' => 5, 'name' => ''],
],
'limit' => 2,
'page' => $currentPage,
];
$paginator = $factory->newInstance('nativeArray', $options);
<?php
declare(strict_types=1);
use MyApp\Models\Invoices;
use Phalcon\Paginator\PaginatorFactory;
$factory = new PaginatorFactory();
$currentPage = 2;
$builder = $this
->modelsManager
->createBuilder()
->columns('id, name')
->from('Robots')
->orderBy('name');
$options = [
'builder' => $builder,
'limit' => 20,
'page' => $currentPage,
];
$paginator = $factory->newInstance('queryBuilder', $options);
单个类¶
每个适配器必须使用的源数据示例:
模型
<?php
declare(strict_types=1);
use Phalcon\Paginator\Adapter\Model as PaginatorModel;
$currentPage = 2;
$paginator = new PaginatorModel(
[
'model' => Invoices::class,
'limit' => 10,
'page' => $currentPage,
]
);
数组
<?php
declare(strict_types=1);
use Phalcon\Paginator\Adapter\NativeArray as PaginatorArray;
$currentPage = 2;
$paginator = new PaginatorArray(
[
'data' => [
['id' => 1, 'name' => 'Artichoke'],
['id' => 2, 'name' => 'Carrots'],
['id' => 3, 'name' => 'Beet'],
['id' => 4, 'name' => 'Lettuce'],
['id' => 5, 'name' => ''],
],
'limit' => 2,
'page' => $currentPage,
]
);
查询生成器
<?php
declare(strict_types=1);
use MyApp\Models\Invoices;
use Phalcon\Paginator\Adapter\QueryBuilder as PaginatorQueryBuilder;
$currentPage = 2;
$builder = $this
->modelsManager
->createBuilder()
->columns('id, name')
->from('Robots')
->orderBy('name');
$paginator = new PaginatorQueryBuilder(
[
'builder' => $builder,
'limit' => 20,
'page' => $currentPage,
]
);
自定义¶
The Phalcon\分页器\AdapterInterface接口必须被实现,以创建您自己的分页器适配器或扩展现有的适配器:
<?php
declare(strict_types=1);
use Phalcon\Paginator\AdapterInterface as PaginatorInterface;
use Phalcon\Paginator\RepositoryInterface;
class MyPaginator implements PaginatorInterface
{
/**
* Get current rows limit
*/
public function getLimit(): int;
/**
* Returns a slice of the resultset to show in the pagination
*/
public function paginate(): RepositoryInterface;
/**
* Set the current page number
*/
public function setCurrentPage(int $page);
/**
* Set current rows limit
*/
public function setLimit(int $limit);
}