Pagination


Pagination - 图1

Overview

The process of pagination takes place when we need to present big groups of arbitrary data gradually. Phalcon\Paginator offers a fast and convenient way to split these sets of data into browsable pages.

Data Adapters

This component makes use of adapters to encapsulate different sources of data:

AdapterDescription
Phalcon\Paginator\Adapter\NativeArrayUse a PHP array as source data
Phalcon\Paginator\Adapter\ModelUse a Phalcon\Mvc\Model\Resultset object as source data. Since PDO doesn’t support scrollable cursors this adapter shouldn’t be used to paginate a large number of records
Phalcon\Paginator\Adapter\QueryBuilderUse a Phalcon\Mvc\Model\Query\Builder object as source data

Factory

New Instance

You can use the Pagination Factory class to instantiate a new paginator object:

  1. <?php
  2. use Phalcon\Paginator\PaginatorFactory;
  3. $builder = $this
  4. ->modelsManager
  5. ->createBuilder()
  6. ->columns('id, name')
  7. ->from(Users::class)
  8. ->orderBy('name')
  9. ;
  10. $options = [
  11. 'builder' => $builder,
  12. 'limit' => 20,
  13. 'page' => 1,
  14. ];
  15. $factory = new PaginatorFactory();
  16. $paginator = $factory->newInstance('queryBuilder');

Load

Loads Paginator Adapter class using adapter option. The configuration passed can be an array or a Phalcon\Config object with the necessary entries for the class to be instantiated.

  1. <?php
  2. use Phalcon\Paginator\PaginatorFactory;
  3. $builder = $this
  4. ->modelsManager
  5. ->createBuilder()
  6. ->columns('id, lastName, firstName')
  7. ->from(Users::class)
  8. ->orderBy('name')
  9. ;
  10. $options = [
  11. 'builder' => $builder,
  12. 'limit' => 20,
  13. 'page' => 1,
  14. 'adapter' => 'queryBuilder',
  15. ];
  16. $paginator = (new PaginatorFactory())->load($options);

Examples

In the example below, the paginator will use the result of a query from a model as its source data, and limit the displayed data to 10 records per page:

  1. <?php
  2. use Phalcon\Paginator\Adapter\Model as PaginatorModel;
  3. // Current page to show
  4. // In a controller/component this can be:
  5. // $this->request->getQuery('page', 'int'); // GET
  6. // $this->request->getPost('page', 'int'); // POST
  7. $currentPage = (int) $_GET['page'];
  8. // The data set to paginate
  9. $robots = Users::find();
  10. // Create a Model paginator, show 10 rows by page starting from $currentPage
  11. $paginator = new PaginatorModel(
  12. [
  13. 'data' => $robots,
  14. 'limit' => 10,
  15. 'page' => $currentPage,
  16. ]
  17. );
  18. // Get the paginated results
  19. $page = $paginator->paginate();

The $currentPage variable controls the page to be displayed. The $paginator->paginate() returns a $page object that contains the paginated data. It can be used for generating the pagination:

  1. <table>
  2. <tr>
  3. <th>Id</th>
  4. <th>Active</th>
  5. <th>Last Name</th>
  6. <th>First Name</th>
  7. </tr>
  8. <?php foreach ($page->items as $item) { ?>
  9. <tr>
  10. <td><?php echo $item->id; ?></td>
  11. <td><?php echo ($item->active) ? 'Y' : 'N'; ?></td>
  12. <td><?php echo $item->lastName; ?></td>
  13. <td><?php echo $item->firstName; ?></td>
  14. </tr>
  15. <?php } ?>
  16. </table>

The $page object also contains navigation data:

  1. <a href="/users/list">First</a>
  2. <a href="/users/list?page=<?= $page->previous; ?>">Previous</a>
  3. <a href="/users/list?page=<?= $page->next; ?>">Next</a>
  4. <a href="/users/list?page=<?= $page->last; ?>">Last</a>
  5. <?php echo "You are in page {$page->current} of {$page->total_pages}"; ?>

Using Adapters

Factory

You can instantiate a Paginator class using the AdapterFactory.

  1. <?php
  2. use Phalcon\Paginator\AdapterFactory;
  3. $factory = new AdapterFactory();
  4. // Passing a resultset as data
  5. $options = [
  6. 'data' => Products::find(),
  7. 'limit' => 10,
  8. 'page' => $currentPage,
  9. ];
  10. $paginator = $factory->newInstance('model', $options);
  11. // Passing an array as data
  12. $options = [
  13. 'data' => [
  14. ['id' => 1, 'name' => 'Artichoke'],
  15. ['id' => 2, 'name' => 'Carrots'],
  16. ['id' => 3, 'name' => 'Beet'],
  17. ['id' => 4, 'name' => 'Lettuce'],
  18. ['id' => 5, 'name' => ''],
  19. ],
  20. 'limit' => 2,
  21. 'page' => $currentPage,
  22. ];
  23. $paginator = $factory->newInstance('nativeArray', $options);
  24. // Passing a QueryBuilder as data
  25. $builder = $this
  26. ->modelsManager
  27. ->createBuilder()
  28. ->columns('id, name')
  29. ->from('Robots')
  30. ->orderBy('name');
  31. $options = [
  32. 'builder' => $builder,
  33. 'limit' => 20,
  34. 'page' => 1,
  35. ];
  36. $paginator = $factory->newInstance('queryBuilder', $options);

Individual classes

An example of the source data that must be used for each adapter:

  1. <?php
  2. use Phalcon\Paginator\Adapter\Model as PaginatorModel;
  3. use Phalcon\Paginator\Adapter\NativeArray as PaginatorArray;
  4. use Phalcon\Paginator\Adapter\QueryBuilder as PaginatorQueryBuilder;
  5. // Passing a resultset as data
  6. $paginator = new PaginatorModel(
  7. [
  8. 'data' => Products::find(),
  9. 'limit' => 10,
  10. 'page' => $currentPage,
  11. ]
  12. );
  13. // Passing an array as data
  14. $paginator = new PaginatorArray(
  15. [
  16. 'data' => [
  17. ['id' => 1, 'name' => 'Artichoke'],
  18. ['id' => 2, 'name' => 'Carrots'],
  19. ['id' => 3, 'name' => 'Beet'],
  20. ['id' => 4, 'name' => 'Lettuce'],
  21. ['id' => 5, 'name' => ''],
  22. ],
  23. 'limit' => 2,
  24. 'page' => $currentPage,
  25. ]
  26. );
  27. // Passing a QueryBuilder as data
  28. $builder = $this->modelsManager->createBuilder()
  29. ->columns('id, name')
  30. ->from('Robots')
  31. ->orderBy('name');
  32. $paginator = new PaginatorQueryBuilder(
  33. [
  34. 'builder' => $builder,
  35. 'limit' => 20,
  36. 'page' => 1,
  37. ]
  38. );

Page Attributes

The $page object has the following attributes:

AttributeDescription
itemsThe set of records to be displayed at the current page
currentThe current page
previousThe previous page to the current one
nextThe next page to the current one
lastThe last page in the set of records
total_itemsThe number of items in the source data

Implementing your own adapters

The Phalcon\Paginator\AdapterInterface interface must be implemented in order to create your own paginator adapters or extend the existing ones:

  1. <?php
  2. use Phalcon\Paginator\AdapterInterface as PaginatorInterface;
  3. use Phalcon\Paginator\RepositoryInterface;
  4. class MyPaginator implements PaginatorInterface
  5. {
  6. /**
  7. * Get current rows limit
  8. */
  9. public function getLimit(): int;
  10. /**
  11. * Returns a slice of the resultset to show in the pagination
  12. */
  13. public function paginate(): RepositoryInterface;
  14. /**
  15. * Set the current page number
  16. */
  17. public function setCurrentPage(int $page);
  18. /**
  19. * Set current rows limit
  20. */
  21. public function setLimit(int $limit);
  22. }