13 Разбивка на страницы
Обзор.
Пагинатор-это компонент, который помогает постепенно разбивать большое количество данных. Примером может быть отображение всех сообщений блога, по 5 за раз. Phalcon Paginator принимает параметры и на их основе возвращает соответствующий срез всего результирующего набора, чтобы разработчик мог представить разбитые на страницы данные.
<?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();
Приведенный выше пример использует массив в качестве источника и ограничивает результаты двумя записями одновременно. Он вернет элементы с идентификаторами 3 и 4, поскольку страница была установлена на 2.
Процесс разбиения на страницы происходит, когда нам нужно постепенно представить большие группы произвольных данных.. Phalcon\Paginator
предлагает быстрый и удобный способ разделить эти наборы данных на просматриваемые страницы.
Адаптер данных.
Этот компонент использует адаптеры для инкапсуляции различных источников данных:
Адаптер | Описание |
---|---|
Phalcon\Paginator\Adapter\NativeArray | Использование массива PHP в качестве исходных данных |
Phalcon\Paginator\Adapter\Model | Использование объекта Phalcon\Mvc\Model\Resultset в качестве исходных данных. Поскольку PDO не поддерживает прокрутку курсоров, этот адаптер не должен использоваться для разбиения на страницы большого количества записей |
Phalcon\Paginator\Adapter\QueryBuilder | Использование объекта Phalcon\Mvc\Model\Query\Builder в качестве источника данных |
Примечание: поскольку PDO не поддерживает прокручиваемые курсоры, Phalcon\Paginator\Adapter\Model не следует использовать для разбиения на страницы большого количества записей
Методы
public function __construct(array $config)
Каждый адаптер требует опций для правильной работы. Эти параметры передаются в виде массива ключ/значение в конструкторе адаптера.
builder
- Used only for the Phalcon\Paginator\Adapter\QueryBuilder to pass the builder objectdata
- The data to paginate. (Phalcon\Paginator\Adapter\NativeArray adapter)limit
-int
- The size of the page slice. Iflimit
is negative, an exception will be thrown.model
- The data to paginate. (Phalcon\Paginator\Adapter\Model adapter)page
-int
- The current pagerepository
- Phalcon\Paginator\RepositoryInterface - Объект репозитория, устанавливающий результирующий набор. Подробнее о репозиториях см. ниже.
Методы, которые подвергаются являются:
getLimit()
-int
- Получить текущий лимит строкgetRepository(array $properties = null)
-RepositoryInterface
- Возвращает текущий репозиторий для разбиения на страницыsetCurrentPage(int $page)
-AdapterInterface
- Установить номер текущей страницыsetLimit(int $limitRows)
-AdapterInterface
- Установить ограничение по текущим строкамsetRepository(RepositoryInterface $repository)
-AdapterInterface
- Установить текущий репозиторий для разбиения на страницы
Модель
Адаптер Phalcon\Paginator\Adapter\Model использует Phalcon\Mvc\Model\Resultset как источник данных. Это результат метода find()
на модели.
<?php 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();
The array accepts model
for the model class to be used. The method find()
will be called on it. Additionally this adapter can accept parameters
as the array that find()
can use with all the relevant conditionals required.
Массив
Адаптер Phalcon\Paginator\Adapter\NativeArray принимает массив PHP в качестве источника данных.
<?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();
Построитель запросов
Адаптер Phalcon\Paginator\Adapter\QueryBuilder использует объект Phalcon\Mvc\Model\Query\Builder для выполнения запроса PHQL к базе данных.
<?php 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();
Repository
Метод paginate()
выполняет всю работу по разбиению данных на страницы. Он возвращает объект Phalcon\Paginator\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 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
You can also create your custom repository class by implementing the Phalcon\Paginator\RepositoryInterface interface.
Фабрика
Вы можете использовать класс pagination Factory для создания экземпляра нового объекта paginator. Названия служб таковы::
model
- Phalcon\Paginator\Adapter\ModelnativeArray
- Phalcon\Paginator\Adapter\NativeArrayqueryBuilder
- Phalcon\Paginator\Adapter\QueryBuilder
Новые случаи
Один из методов, который вы можете использовать - newInstance()
:
<?php 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');
Загрузка
Загружает класс адаптера Paginator, используя опцию adapter
. Передаваемая конфигурация может быть массивом или объектом Phalcon\Config с необходимыми записями для создания экземпляра класса.
<?php 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\Paginator\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 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\Paginator\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>
Объект $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()}"; ?>
Фабрика
Вы можете создать экземпляр класса Paginator с помощью AdapterFactory
.
Модель
<?php 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 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 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 use Phalcon\Paginator\Adapter\Model as PaginatorModel; $currentPage = 2; $paginator = new PaginatorModel( [ 'model' => Invoices::class, 'limit' => 10, 'page' => $currentPage, ] );
Массив
<?php 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 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, ] );
Собственные адаптеры
Для того, чтобы создавать свои собственные адаптеры пагинатора или расширить уже существующие, должен быть реализован интерфейс Phalcon\Paginator\AdapterInterface :
<?php use Phalcon\Paginator\AdapterInterface as PaginatorInterface; use Phalcon\Paginator\RepositoryInterface; class MyPaginator implements PaginatorInterface { /** * Получить текущий лимит строк */ public function getLimit(): int; /** * Возвращает фрагмент результирующего набора для отображения в разбиении на страницы */ public function paginate(): RepositoryInterface; /** * Установите номер текущей страницы */ public function setCurrentPage(int $page); /** * Установить ограничение по текущим строкам */ public function setLimit(int $limit); }