ИспользованиеРазбиение наборов данных на страницы
Для разбиения наборов данных на страницы
Zend_Paginator должен иметь обобщенный
доступ к этим данным. Поэтому доступ к данным осуществляется
через адаптеры к источникам данных. В поставку Zend Framework
по умолчанию входят несколько адаптеров:
Адаптеры для Zend_PaginatorАдаптерОписаниеArrayИспользует PHP-массивDbSelect
Использует экземпляр Zend_Db_Select,
который будет возвращать массив
DbTableSelect
Использует экземпляр Zend_Db_Table_Select,
который будет возвращать объект
Zend_Db_Table_Rowset_Abstract.
Это дает возможность получить такую дополнительную
информацию, как, например, имена столбцов.
Iterator
Использует экземпляр
IteratorNull
Не использовать
Zend_Paginator для разбиения
на страницы.
Но и в этом случае вы можете воспользоваться
возможностями постраничной навигации.
Вместо извлечения всех строк, соответствующих данному
запросу, адаптеры DbSelect and DbTableSelect извлекают
только тот объем данных, который необходим для отображения
текущей страницы.
Поэтому для определения общего количества соответствующих
запросу строк динамически генерируется второй запрос.
Но вы можете сами предоставить
адаптеру количество строк либо запрос для его определения.
См. метод setRowCount()
в адаптере DbSelect для получения более подробной информации.
При создании экземпляра класса
Zend_Paginator следует передавать адаптер его
конструктору:
Для удобства вы можете воспользоваться фабричным методом
factory() для получения адаптеров,
входящих в поставку Zend Framework:
В случае использования адаптера Null вы должны передавать
его конструктору количество элементов вместо набора данных.
Несмотря на то, что на этом этапе экземпляр формально уже пригоден к
использованию, на практике вы должны будете еще
передавать номер страницы, запрошенный пользователем, чтобы он мог
просматривать данные:
setCurrentPageNumber($page);
]]>
Наиболее простым способом отслеживания номера страницы является
использование URL. Мы рекомендуем использовать
для этого совместимый с
Zend_Controller_Router_Interface
маршрутизатор, но это не является обязательным требованием.
Ниже приведен пример маршрута, который можно использовать в
конфигурационном файле INI:
Используя этот маршрут и MVC-компоненты Zend Framework-а,
вы можете устанавливать номер текущей страницы следующим образом:
setCurrentPageNumber($this->_getParam('page'));
]]>
Есть также другие опции, о них читайте в разделе
Конфигурация.
После этого нужно присвоить экземпляр
Zend_Paginator переменной вида. Если
используется Zend_View с помощником
действий ViewRenderer, то для этого подходит следующий код:
view->paginator = $paginator;
]]>Адаптеры DbSelect и DbTableSelect
Хотя большинство адаптеров довольно просто в использовании, адаптеры
баз данных требуют дополнительных пояснений насчет извлечения
данных и подсчета количества строк.
При использовании адаптеры DbSelect и DbTableSelect
нет необходимости самостоятельно извлекать данные. Оба адаптера
сами выполняют извлечение данных и подсчет общего количества
страниц. Если полученные результаты выборки требуют дополнительной
обработки, то адаптер может быть расширен с переопределением
метода getItems().
Эти адаптеры
не извлекают все записи из базы данных для
того, чтобы посчитать их. Вместо этого адаптеры используют
исходный запрос для получения соответствующего COUNT-запроса,
этот запрос выполняется для получения общего количества строк.
Таким образом, производится еще один дополнительный запрос к базе
данных, но это во много раз быстрее, чем извлечение всего результата
и использование count(), особенно в случае
больших объемов данных.
Адаптеры баз данных будут пытаться строить наиболее эффективный
запрос, который будет выполняться практически на всех современных
СУРБД. Но в зависимости от используемой базы данных или даже
выбранной структуры могут быть более эффективные пути получения
количества строк.
На этот случай адаптеры баз данных дают возможность
устанавливать свой COUNT-запрос.
Например, если вы фиксируете количество постов в блоге в отдельной
таблице, то можете достичь более быстрого получения их
количества, написав следующий код:
select()->from('posts'));
$adapter->setRowCount(
$db->select()
->from(
'item_counts',
array(
Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN => 'post_count'
)
)
);
$paginator = new Zend_Paginator($adapter);
]]>
Этот подход может не дать большого выигрыша в производительности
в случае небольшого объема данных или простых запросов на
извлечение.
Однако в случае сложных запросов и больших объемов данных
подобный подход может дать значительный выигрыш
в производительности.
Рендеринг страниц через скрипты видов
Для визуализации элементов страницы (если
вы используете для этого Zend_Paginator)
и отображения постраничной навигации используется скрипт вида.
Поскольку Zend_Paginator реализует
SPL-интерфейс
IteratorAggregate,
то обход элементов и их отображение производится элементарно.