跳转到内容

分页


概览

分页器是一个组件,用于帮助逐步分割大量数据。例如一次显示博客中的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为34的元素,因为page已设置为2.

适配器

对于数据源,该组件使用适配器。它附带以下适配器:

适配器 描述
Phalcon\分页器\适配器\Model 使用Phalcon\Mvc\Model\Resultset对象作为源数据。
Phalcon\分页器\适配器\NativeArray 使用 PHP 数组作为源数据
Phalcon\分页器\适配器\QueryBuilder 使用Phalcon\Mvc\Model\Query\Builder对象作为源数据

注意

因为 PDO 不支持可滚动游标,Phalcon\分页器\适配器\Model不应该用来分页大量记录

方法

public function __construct(array $config)

每个适配器都需要选项才能正常运行。这些选项在适配器的构造函数中以键/值数组形式传递。

选项 描述
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);

示例配置对象如下:

[paginator]
adapter = queryBuilder
options.limit = 20
options.page = 1

配置期望一个元素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);
}
无噪 Logo
无噪文档
25 年 6 月翻译
版本号 5.9
文档源↗