2
0

Zend_Paginator-Usage.xml 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.paginator.usage">
  4. <title>Использование</title>
  5. <sect2 id="zend.paginator.usage.paginating">
  6. <title>Разбиение наборов данных на страницы </title>
  7. <para>
  8. Для разбиения наборов данных на страницы
  9. <classname>Zend_Paginator</classname> должен иметь обобщенный
  10. доступ к этим данным. Поэтому доступ к данным осуществляется
  11. через адаптеры к источникам данных. В поставку Zend Framework
  12. по умолчанию входят несколько адаптеров:
  13. </para>
  14. <table id="zend.paginator.usage.paginating.adapters">
  15. <title>Адаптеры для Zend_Paginator</title>
  16. <tgroup cols="2">
  17. <thead>
  18. <row>
  19. <entry>Адаптер</entry>
  20. <entry>Описание</entry>
  21. </row>
  22. </thead>
  23. <tbody>
  24. <row>
  25. <entry>Array</entry>
  26. <entry>Использует PHP-массив</entry>
  27. </row>
  28. <row>
  29. <entry>DbSelect</entry>
  30. <entry>
  31. Использует экземпляр <link
  32. linkend="zend.db.select"><classname>Zend_Db_Select</classname></link>,
  33. который будет возвращать массив
  34. </entry>
  35. </row>
  36. <row>
  37. <entry>DbTableSelect</entry>
  38. <entry>
  39. Использует экземпляр <link
  40. linkend="zend.db.table.fetch-all"><classname>Zend_Db_Table_Select</classname></link>,
  41. который будет возвращать объект
  42. <classname>Zend_Db_Table_Rowset_Abstract</classname>.
  43. Это дает возможность получить такую дополнительную
  44. информацию, как, например, имена столбцов.
  45. </entry>
  46. </row>
  47. <row>
  48. <entry>Iterator</entry>
  49. <entry>
  50. Использует экземпляр
  51. <ulink url="http://www.php.net/~helly/php/ext/spl/interfaceIterator.html"><classname>Iterator</classname></ulink>
  52. </entry>
  53. </row>
  54. <row>
  55. <entry>Null</entry>
  56. <entry>
  57. Не использовать
  58. <classname>Zend_Paginator</classname> для разбиения
  59. на страницы.
  60. Но и в этом случае вы можете воспользоваться
  61. возможностями постраничной навигации.
  62. </entry>
  63. </row>
  64. </tbody>
  65. </tgroup>
  66. </table>
  67. <note>
  68. <para>
  69. Вместо извлечения всех строк, соответствующих данному
  70. запросу, адаптеры DbSelect and DbTableSelect извлекают
  71. только тот объем данных, который необходим для отображения
  72. текущей страницы.
  73. </para>
  74. <para>
  75. Поэтому для определения общего количества соответствующих
  76. запросу строк динамически генерируется второй запрос.
  77. Но вы можете сами предоставить
  78. адаптеру количество строк либо запрос для его определения.
  79. См. метод <methodname>setRowCount()</methodname>
  80. в адаптере DbSelect для получения более подробной информации.
  81. </para>
  82. </note>
  83. <para>
  84. При создании экземпляра класса
  85. <classname>Zend_Paginator</classname> следует передавать адаптер его
  86. конструктору:
  87. </para>
  88. <programlisting language="php"><![CDATA[
  89. $paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Array($array));
  90. ]]></programlisting>
  91. <para>
  92. Для удобства вы можете воспользоваться фабричным методом
  93. <methodname>factory()</methodname> для получения адаптеров,
  94. входящих в поставку Zend Framework:
  95. </para>
  96. <programlisting language="php"><![CDATA[
  97. $paginator = Zend_Paginator::factory($array);
  98. ]]></programlisting>
  99. <note>
  100. <para>
  101. В случае использования адаптера Null вы должны передавать
  102. его конструктору количество элементов вместо набора данных.
  103. </para>
  104. </note>
  105. <para>
  106. Несмотря на то, что на этом этапе экземпляр формально уже пригоден к
  107. использованию, на практике вы должны будете еще
  108. передавать номер страницы, запрошенный пользователем, чтобы он мог
  109. просматривать данные:
  110. </para>
  111. <programlisting language="php"><![CDATA[
  112. $paginator->setCurrentPageNumber($page);
  113. ]]></programlisting>
  114. <para>
  115. Наиболее простым способом отслеживания номера страницы является
  116. использование <acronym>URL</acronym>. Мы рекомендуем использовать
  117. для этого совместимый с
  118. <classname>Zend_Controller_Router_Interface</classname>
  119. маршрутизатор, но это не является обязательным требованием.
  120. </para>
  121. <para>
  122. Ниже приведен пример маршрута, который можно использовать в
  123. конфигурационном файле <acronym>INI</acronym>:
  124. </para>
  125. <programlisting language="php"><![CDATA[
  126. routes.example.route = articles/:articleName/:page
  127. routes.example.defaults.controller = articles
  128. routes.example.defaults.action = view
  129. routes.example.defaults.page = 1
  130. routes.example.reqs.articleName = \w+
  131. routes.example.reqs.page = \d+
  132. ]]></programlisting>
  133. <para>
  134. Используя этот маршрут и MVC-компоненты Zend Framework-а,
  135. вы можете устанавливать номер текущей страницы следующим образом:
  136. </para>
  137. <programlisting language="php"><![CDATA[
  138. $paginator->setCurrentPageNumber($this->_getParam('page'));
  139. ]]></programlisting>
  140. <para>
  141. Есть также другие опции, о них читайте в разделе
  142. <link linkend="zend.paginator.configuration">Конфигурация</link>.
  143. </para>
  144. <para>
  145. После этого нужно присвоить экземпляр
  146. <classname>Zend_Paginator</classname> переменной вида. Если
  147. используется <classname>Zend_View</classname> с помощником
  148. действий ViewRenderer, то для этого подходит следующий код:
  149. </para>
  150. <programlisting language="php"><![CDATA[
  151. $this->view->paginator = $paginator;
  152. ]]></programlisting>
  153. </sect2>
  154. <sect2 id="zend.paginator.usage.dbselect">
  155. <title>Адаптеры DbSelect и DbTableSelect</title>
  156. <para>
  157. Хотя большинство адаптеров довольно просто в использовании, адаптеры
  158. баз данных требуют дополнительных пояснений насчет извлечения
  159. данных и подсчета количества строк.
  160. </para>
  161. <para>
  162. При использовании адаптеры DbSelect и DbTableSelect
  163. нет необходимости самостоятельно извлекать данные. Оба адаптера
  164. сами выполняют извлечение данных и подсчет общего количества
  165. страниц. Если полученные результаты выборки требуют дополнительной
  166. обработки, то адаптер может быть расширен с переопределением
  167. метода <methodname>getItems()</methodname>.
  168. </para>
  169. <para>
  170. Эти адаптеры
  171. <emphasis>не</emphasis> извлекают все записи из базы данных для
  172. того, чтобы посчитать их. Вместо этого адаптеры используют
  173. исходный запрос для получения соответствующего COUNT-запроса,
  174. этот запрос выполняется для получения общего количества строк.
  175. Таким образом, производится еще один дополнительный запрос к базе
  176. данных, но это во много раз быстрее, чем извлечение всего результата
  177. и использование <methodname>count()</methodname>, особенно в случае
  178. больших объемов данных.
  179. </para>
  180. <para>
  181. Адаптеры баз данных будут пытаться строить наиболее эффективный
  182. запрос, который будет выполняться практически на всех современных
  183. СУРБД. Но в зависимости от используемой базы данных или даже
  184. выбранной структуры могут быть более эффективные пути получения
  185. количества строк.
  186. На этот случай адаптеры баз данных дают возможность
  187. устанавливать свой COUNT-запрос.
  188. Например, если вы фиксируете количество постов в блоге в отдельной
  189. таблице, то можете достичь более быстрого получения их
  190. количества, написав следующий код:
  191. </para>
  192. <programlisting language="php"><![CDATA[
  193. $adapter = new Zend_Paginator_Adapter_DbSelect($db->select()->from('posts'));
  194. $adapter->setRowCount(
  195. $db->select()
  196. ->from(
  197. 'item_counts',
  198. array(
  199. Zend_Paginator_Adapter_DbSelect::ROW_COUNT_COLUMN => 'post_count'
  200. )
  201. )
  202. );
  203. $paginator = new Zend_Paginator($adapter);
  204. ]]></programlisting>
  205. <para>
  206. Этот подход может не дать большого выигрыша в производительности
  207. в случае небольшого объема данных или простых запросов на
  208. извлечение.
  209. Однако в случае сложных запросов и больших объемов данных
  210. подобный подход может дать значительный выигрыш
  211. в производительности.
  212. </para>
  213. </sect2>
  214. <sect2 id="zend.paginator.rendering">
  215. <title>Рендеринг страниц через скрипты видов</title>
  216. <para>
  217. Для визуализации элементов страницы (если
  218. вы используете для этого <classname>Zend_Paginator</classname>)
  219. и отображения постраничной навигации используется скрипт вида.
  220. </para>
  221. <para>
  222. Поскольку <classname>Zend_Paginator</classname> реализует
  223. SPL-интерфейс
  224. <ulink url="http://www.php.net/~helly/php/ext/spl/interfaceIteratorAggregate.html"><classname>IteratorAggregate</classname></ulink>,
  225. то обход элементов и их отображение производится элементарно.
  226. </para>
  227. <programlisting language="php"><![CDATA[
  228. <html>
  229. <body>
  230. <h1>Example</h1>
  231. <?php if (count($this->paginator)): ?>
  232. <ul>
  233. <?php foreach ($this->paginator as $item): ?>
  234. <li><?php echo $item; ?></li>
  235. <?php endforeach; ?>
  236. </ul>
  237. <?php endif; ?>
  238. <?php echo $this->paginationControl($this->paginator,
  239. 'Sliding',
  240. 'my_pagination_control.phtml'); ?>
  241. </body>
  242. </html>
  243. ]]></programlisting>
  244. <para>
  245. Обратите внимание, что в конце вызывается помощник вида.
  246. PaginationControl принимает экземпляр
  247. <classname>Zend_Paginator</classname>, стиль прокрутки, скрипт
  248. вида и массив дополнительных параметров.
  249. </para>
  250. <para>
  251. Второй и третий параметры очень важны. В то время как скрипт вида
  252. используется для определения <emphasis>внешнего вида</emphasis>
  253. постраничной навигации, стиль прокрутки определяет ее
  254. <emphasis>поведение</emphasis>.
  255. Предположим, скрипт вида отображает постраничную навигацию
  256. для результатов поиска следующего вида:
  257. </para>
  258. <para>
  259. <inlinegraphic align="center" valign="middle"
  260. fileref="figures/zend.paginator.usage.rendering.control.png"
  261. format="PNG"/>
  262. </para>
  263. <para>
  264. Что должно происходить, если пользователь нажимает на ссылку "next"
  265. несколько раз? Действительно, тут может быть сколько угодно
  266. вариантов. Номер текущей страницы может оставаться в середине
  267. (как это реализовано, например, в Yahoo!) или перемещаться к концу
  268. ряда при каждом нажатии "next" и затем показываться снова с другого
  269. конца. Количество отображаемых номеров страниц может даже
  270. увеличиваться и уменьшаться, пока пользователь перемещается по ним
  271. (или "прокручивает" их), как это сделано в Google.
  272. </para>
  273. <para>
  274. Zend Framework предоставляет четыре стиля прокрутки:
  275. </para>
  276. <table id="zend.paginator.usage.rendering.scrolling-styles">
  277. <title>Стили прокрутки для Zend_Paginator</title>
  278. <tgroup cols="2">
  279. <thead>
  280. <row>
  281. <entry>Стиль прокрутки</entry>
  282. <entry>Описание</entry>
  283. </row>
  284. </thead>
  285. <tbody>
  286. <row>
  287. <entry>All</entry>
  288. <entry>
  289. Возвращает все страницы. Полезен для
  290. постраничной навигации в виде выпадающего списка
  291. с относительно небольшим количеством страниц.
  292. В этом случае предпочтительнее, чтобы в нем
  293. отображались все доступные страницы.
  294. </entry>
  295. </row>
  296. <row>
  297. <entry>Elastic</entry>
  298. <entry>
  299. Скроллинг в стиле Google, в котором количество
  300. отображаемых номеров страниц может увеличиваться и
  301. уменьшаться, пока пользователь перемещается по
  302. страницам.
  303. </entry>
  304. </row>
  305. <row>
  306. <entry>Jumping</entry>
  307. <entry>
  308. Пока пользователь листает страницы, номер текущей
  309. страницы перемещается к концу ряда и показывается
  310. снова в начале нового ряда.
  311. </entry>
  312. </row>
  313. <row>
  314. <entry>Sliding</entry>
  315. <entry>
  316. Скроллинг в стиле Yahoo!, в котором номер текущей
  317. страницы находится в середине ряда или настолько
  318. близко к нему, насколько это возможно. Этот стиль
  319. используется по умолчанию.
  320. </entry>
  321. </row>
  322. </tbody>
  323. </tgroup>
  324. </table>
  325. <para>
  326. Четвертый и последний параметр предназначается для ассоциативного
  327. массива дополнительных переменных, которые должны быть доступны в
  328. вашем скрипте вида (через <varname>$this</varname>).
  329. Например, эти значения могут включать в себя дополнительные
  330. параметры <acronym>URL</acronym> для подстановки в ссылки
  331. постраничной навигации.
  332. </para>
  333. <para>
  334. Установив используемые по умолчанию скрипт вида, стиль прокрутки и
  335. экземпляр вида, вы можете полностью исключить вызовы
  336. PaginationControl:
  337. </para>
  338. <programlisting language="php"><![CDATA[
  339. Zend_Paginator::setDefaultScrollingStyle('Sliding');
  340. Zend_View_Helper_PaginationControl::setDefaultViewPartial(
  341. 'my_pagination_control.phtml'
  342. );
  343. $paginator->setView($view);
  344. ]]></programlisting>
  345. <para>
  346. Если все эти значения установлены, то вы можете вывести
  347. постраничную навигацию в своем скрипте вида с помощью обычной
  348. конструкции echo:
  349. </para>
  350. <programlisting language="php"><![CDATA[
  351. <?php echo $this->paginator; ?>
  352. ]]></programlisting>
  353. <note>
  354. <para>
  355. Разумеется, можно использовать
  356. <classname>Zend_Paginator</classname> с другими
  357. шаблонизаторами. Например, со Smarty вы можете делать
  358. следующее:
  359. </para>
  360. <programlisting language="php"><![CDATA[
  361. $smarty->assign('pages', $paginator->getPages());
  362. ]]></programlisting>
  363. <para>
  364. Вы можете затем обращаться к установленным значениям из
  365. шаблона, как в коде ниже:
  366. </para>
  367. <programlisting language="php"><![CDATA[
  368. {$pages->pageCount}
  369. ]]></programlisting>
  370. </note>
  371. <sect3 id="zend.paginator.usage.rendering.example-controls">
  372. <title>Примеры постраничной навигации</title>
  373. <para>
  374. Надеемся, следующие примеры помогут начать работать с
  375. <classname>Zend_Paginator</classname>:
  376. </para>
  377. <para>
  378. Постраничная навигация для результатов поиска:
  379. </para>
  380. <programlisting language="php"><![CDATA[
  381. <!--
  382. См. http://developer.yahoo.com/ypatterns/pattern.php?pattern=searchpagination
  383. -->
  384. <?php if ($this->pageCount): ?>
  385. <div class="paginationControl">
  386. <!-- Ссылка на предыдущую страницу -->
  387. <?php if (isset($this->previous)): ?>
  388. <a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
  389. &lt; Previous
  390. </a> |
  391. <?php else: ?>
  392. <span class="disabled">&lt; Previous</span> |
  393. <?php endif; ?>
  394. <!-- Нумерованные ссылки на страницы -->
  395. <?php foreach ($this->pagesInRange as $page): ?>
  396. <?php if ($page != $this->current): ?>
  397. <a href="<?php echo $this->url(array('page' => $page)); ?>">
  398. <?php echo $page; ?>
  399. </a> |
  400. <?php else: ?>
  401. <?php echo $page; ?> |
  402. <?php endif; ?>
  403. <?php endforeach; ?>
  404. <!-- Ссылка на следующую страницу -->
  405. <?php if (isset($this->next)): ?>
  406. <a href="<?php echo $this->url(array('page' => $this->next)); ?>">
  407. Next &gt;
  408. </a>
  409. <?php else: ?>
  410. <span class="disabled">Next &gt;</span>
  411. <?php endif; ?>
  412. </div>
  413. <?php endif; ?>
  414. ]]></programlisting>
  415. <para>
  416. Постраничная навигация для элементов:
  417. </para>
  418. <programlisting language="php"><![CDATA[
  419. <!--
  420. См. http://developer.yahoo.com/ypatterns/pattern.php?pattern=itempagination
  421. -->
  422. <?php if ($this->pageCount): ?>
  423. <div class="paginationControl">
  424. <?php echo $this->firstItemNumber; ?> - <?php echo $this->lastItemNumber; ?>
  425. of <?php echo $this->totalItemCount; ?>
  426. <!-- Ссылка на первую страницу -->
  427. <?php if (isset($this->previous)): ?>
  428. <a href="<?php echo $this->url(array('page' => $this->first)); ?>">
  429. First
  430. </a> |
  431. <?php else: ?>
  432. <span class="disabled">First</span> |
  433. <?php endif; ?>
  434. <!-- Ссылка на предыдущую страницу -->
  435. <?php if (isset($this->previous)): ?>
  436. <a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
  437. &lt; Previous
  438. </a> |
  439. <?php else: ?>
  440. <span class="disabled">&lt; Previous</span> |
  441. <?php endif; ?>
  442. <!-- Ссылка на следующую страницу -->
  443. <?php if (isset($this->next)): ?>
  444. <a href="<?php echo $this->url(array('page' => $this->next)); ?>">
  445. Next &gt;
  446. </a> |
  447. <?php else: ?>
  448. <span class="disabled">Next &gt;</span> |
  449. <?php endif; ?>
  450. <!-- Ссылка на последнюю страницу -->
  451. <?php if (isset($this->next)): ?>
  452. <a href="<?php echo $this->url(array('page' => $this->last)); ?>">
  453. Last
  454. </a>
  455. <?php else: ?>
  456. <span class="disabled">Last</span>
  457. <?php endif; ?>
  458. </div>
  459. <?php endif; ?>
  460. ]]></programlisting>
  461. <para>
  462. Постраничная навигация в виде выпадающего списка:
  463. </para>
  464. <programlisting language="php"><![CDATA[
  465. <?php if ($this->pageCount): ?>
  466. <select id="paginationControl" size="1">
  467. <?php foreach ($this->pagesInRange as $page): ?>
  468. <?php $selected = ($page == $this->current) ? ' selected="selected"' : ''; ?>
  469. <option value="<?php
  470. echo $this->url(array('page' => $page));?>"<?php echo $selected ?>>
  471. <?php echo $page; ?>
  472. </option>
  473. <?php endforeach; ?>
  474. </select>
  475. <?php endif; ?>
  476. <script type="text/javascript"
  477. src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js">
  478. </script>
  479. <script type="text/javascript">
  480. $('paginationControl').observe('change', function() {
  481. window.location = this.options[this.selectedIndex].value;
  482. })
  483. </script>
  484. ]]></programlisting>
  485. </sect3>
  486. <sect3 id="zend.paginator.usage.rendering.properties">
  487. <title>Список свойств</title>
  488. <para>
  489. Следующие опции доступны внутри скрипта вида для постраничной
  490. навигации:
  491. </para>
  492. <table id="zend.paginator.usage.rendering.properties.table">
  493. <title>Свойства, доступные в скрипте вида</title>
  494. <tgroup cols="3">
  495. <thead>
  496. <row>
  497. <entry>Свойство</entry>
  498. <entry>Тип</entry>
  499. <entry>Описание</entry>
  500. </row>
  501. </thead>
  502. <tbody>
  503. <row>
  504. <entry>first</entry>
  505. <entry>integer</entry>
  506. <entry>Номер первой страницы (т.е. 1)</entry>
  507. </row>
  508. <row>
  509. <entry>firstItemNumber</entry>
  510. <entry>integer</entry>
  511. <entry>
  512. Действительный номер первого элемента на
  513. текущей странице
  514. </entry>
  515. </row>
  516. <row>
  517. <entry>firstPageInRange</entry>
  518. <entry>integer</entry>
  519. <entry>
  520. Первая страница в ряде, возвращенном текущим
  521. стилем прокрутки
  522. </entry>
  523. </row>
  524. <row>
  525. <entry>current</entry>
  526. <entry>integer</entry>
  527. <entry>Текущий номер страницы</entry>
  528. </row>
  529. <row>
  530. <entry>currentItemCount</entry>
  531. <entry>integer</entry>
  532. <entry>Количество элементов на текущей странице</entry>
  533. </row>
  534. <row>
  535. <entry>itemCountPerPage</entry>
  536. <entry>integer</entry>
  537. <entry>
  538. Максимальное количество отображаемых
  539. на странице элементов
  540. </entry>
  541. </row>
  542. <row>
  543. <entry>last</entry>
  544. <entry>integer</entry>
  545. <entry>Номер последней страницы</entry>
  546. </row>
  547. <row>
  548. <entry>lastItemNumber</entry>
  549. <entry>integer</entry>
  550. <entry>
  551. Действительный номер последнего элемента на
  552. текущей странице
  553. </entry>
  554. </row>
  555. <row>
  556. <entry>lastPageInRange</entry>
  557. <entry>integer</entry>
  558. <entry>
  559. Последняя страница в ряде, возвращенном текущим
  560. стилем прокрутки
  561. </entry>
  562. </row>
  563. <row>
  564. <entry>next</entry>
  565. <entry>integer</entry>
  566. <entry>Номер следующей страницы</entry>
  567. </row>
  568. <row>
  569. <entry>pageCount</entry>
  570. <entry>integer</entry>
  571. <entry>Общее количество страниц</entry>
  572. </row>
  573. <row>
  574. <entry>pagesInRange</entry>
  575. <entry>array</entry>
  576. <entry>
  577. Массив страниц, возвращенный текущим стилем
  578. прокрутки
  579. </entry>
  580. </row>
  581. <row>
  582. <entry>previous</entry>
  583. <entry>integer</entry>
  584. <entry>Номер предыдущей страницы</entry>
  585. </row>
  586. <row>
  587. <entry>totalItemCount</entry>
  588. <entry>integer</entry>
  589. <entry>Общее количество элементов</entry>
  590. </row>
  591. </tbody>
  592. </tgroup>
  593. </table>
  594. </sect3>
  595. </sect2>
  596. </sect1>
  597. <!--
  598. vim:se ts=4 sw=4 et:
  599. -->