Zend_Paginator-Advanced.xml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.paginator.advanced">
  4. <title>Расширенное использование</title>
  5. <sect2 id="zend.paginator.advanced.adapters">
  6. <title>Создание собственных адаптеров к источникам данных</title>
  7. <para>
  8. Вы можете столкнуться с таким типом источника данных, для которого
  9. в Zend Framework-е не предусмотрено адаптера. В этом случае
  10. нужно создать собственный адаптер.
  11. </para>
  12. <para>
  13. Для этого нужно реализовать интерфейс
  14. <classname>Zend_Paginator_Adapter_Interface</classname>. Он включает
  15. в себя два метода:
  16. </para>
  17. <itemizedlist>
  18. <listitem>
  19. <para>count()</para>
  20. </listitem>
  21. <listitem>
  22. <para>getItems($offset, $itemCountPerPage)</para>
  23. </listitem>
  24. </itemizedlist>
  25. <para>
  26. Кроме того, нужно реализовать конструктор, который принимает
  27. источник данных в качестве параметра и сохраняет его в
  28. защищенном или закрытом свойстве. Как его обрабатывать -
  29. зависит от вас.
  30. </para>
  31. <para>
  32. Если вы когда-либо использовали SPL-интерфейс
  33. <ulink url="http://www.php.net/~helly/php/ext/spl/interfaceCountable.html"><classname>Countable</classname></ulink>,
  34. то вам должно быть известно о назначении метода
  35. <methodname>count()</methodname>. В
  36. <classname>Zend_Paginator</classname> он возвращает общее количество
  37. элементов в наборе данных.
  38. Кроме того, объект <classname>Zend_Paginator</classname>
  39. предоставляет метод <methodname>countAllItems()</methodname>
  40. который служит посредником к методу адаптера
  41. <methodname>count()</methodname>.
  42. </para>
  43. <para>
  44. Метод <methodname>getItems()</methodname> ненамного сложнее.
  45. Он должен принимать смещение и количество элементов на странице
  46. и возвращать соответствующий кусок данных. В случае массива он
  47. мог бы выглядеть следующим образом:
  48. </para>
  49. <programlisting language="php"><![CDATA[
  50. return array_slice($this->_array, $offset, $itemCountPerPage);
  51. ]]></programlisting>
  52. <para>
  53. Посмотрите исходники адаптеров, входящих в поставку
  54. Zend Framework (все они реализуют
  55. <classname>Zend_Paginator_Adapter_Interface</classname>), чтобы
  56. получить представление о том, как можно реализовать свой адаптер.
  57. </para>
  58. </sect2>
  59. <sect2 id="zend.paginator.advanced.scrolling-styles">
  60. <title>Создание своих стилей прокрутки</title>
  61. <para>
  62. При создании своего стиля прокрутки реализуйте интерфейс
  63. <classname>Zend_Paginator_ScrollingStyle_Interface</classname>,
  64. который определяет единственный метод,
  65. <methodname>getPages()</methodname>:
  66. </para>
  67. <programlisting language="php"><![CDATA[
  68. public function getPages(Zend_Paginator $paginator, $pageRange = null);
  69. ]]></programlisting>
  70. <para>
  71. Этот метод должен определять номера пограничных
  72. страниц в ряде так называемых "локальных" страниц (т.е. страниц,
  73. которые находятся рядом с текущей страницей).
  74. </para>
  75. <para>
  76. Если только ваш стиль прокрутки не наследует от уже существующего
  77. (для примера смотрите
  78. <classname>Zend_Paginator_ScrollingStyle_Elastic</classname>), то
  79. этот метод должен иметь в конце что-то вроде следующего:
  80. </para>
  81. <programlisting language="php"><![CDATA[
  82. return $paginator->getPagesInRange($lowerBound, $upperBound);
  83. ]]></programlisting>
  84. <para>
  85. Этим вызовом не делается ничего особенного. Этот метод просто
  86. для удобства - он проверяет на корректность верхний и нижний
  87. пределы и возвращает массив номеров страниц для постраничной
  88. навигации.
  89. </para>
  90. <para>
  91. Для того, чтобы использовать новый стиль прокрутки,
  92. следует указать <classname>Zend_Paginator</classname>-у, в какой
  93. директории этот стиль находится. Для этого сделайте следующее:
  94. </para>
  95. <programlisting language="php"><![CDATA[
  96. $prefix = 'My_Paginator_ScrollingStyle';
  97. $path = 'My/Paginator/ScrollingStyle/';
  98. Zend_Paginator::addScrollingStylePrefixPath($prefix, $path);
  99. ]]></programlisting>
  100. </sect2>
  101. <sect2 id="zend.paginator.advanced.caching">
  102. <title>Возможности кэширования</title>
  103. <para>
  104. Можно указать <classname>Zend_Paginator</classname>-у, чтобы он
  105. кэшировал получаемые данные, чтобы они не извлекались через
  106. адаптер всякий раз, когда будет в них нужда.
  107. Для этого просто передайте его методу
  108. <methodname>setCache()</methodname> экземпляр
  109. <classname>Zend_Cache_Core</classname>.
  110. </para>
  111. <para>
  112. <programlisting language="php"><![CDATA[
  113. $paginator = Zend_Paginator::factory($someData);
  114. $fO = array('lifetime' => 3600, 'automatic_serialization' => true);
  115. $bO = array('cache_dir'=>'/tmp');
  116. $cache = Zend_cache::factory('Core', 'File', $fO, $bO);
  117. Zend_Paginator::setCache($cache);
  118. ]]></programlisting>
  119. </para>
  120. <para>
  121. После того, как <classname>Zend_Paginator</classname> получит
  122. экземпляр <classname>Zend_Cache_Core</classname>, все данные будут
  123. кэшироваться. Иногда возникает необходимость отключать кэширование
  124. данных даже после того, как вы передали эекземпляр
  125. <classname>Zend_Cache_Core</classname>. Для этого вы можете
  126. использовать метод <methodname>setCacheEnable()</methodname>.
  127. </para>
  128. <para>
  129. <programlisting language="php"><![CDATA[
  130. $paginator = Zend_Paginator::factory($someData);
  131. // $cache является экземпляром
  132. Zend_Paginator::setCache($cache);
  133. // ... ниже в коде
  134. $paginator->setCacheEnable(false);
  135. // теперь кэширование отключено
  136. ]]></programlisting>
  137. </para>
  138. <para>
  139. После того, как был установлен объект для кэширования, данные будут
  140. сохраняться и извлекаться через него. Иногда бывает нужно очищать
  141. кэш вручную.
  142. Вы можете делать это через вызов метода
  143. <methodname>clearPageItemCache($pageNumber)</methodname>.
  144. В качестве аргумента метод принимает номер страницы, кэш
  145. которой следует очистить.
  146. Если вызов производится без передачи параметра, то весь кэш будет
  147. очищен:
  148. </para>
  149. <para>
  150. <programlisting language="php"><![CDATA[
  151. $paginator = Zend_Paginator::factory($someData);
  152. Zend_Paginator::setCache($cache);
  153. $items = $paginator->getCurrentItems();
  154. // теперь страница 1 в кэше
  155. $page3Items = $paginator->getItemsByPage(3);
  156. // теперь и страница 3 в кэше
  157. // очищение кэша результатов для страницы 3
  158. $paginator->clearPageItemCache(3);
  159. // очищение всего кэша
  160. $paginator->clearPageItemCache();
  161. ]]></programlisting>
  162. </para>
  163. <para>
  164. Изменение количества элементов на странице приведет к очищению
  165. всего кэша, поскольку после этого он должен потерять актуальность:
  166. </para>
  167. <para>
  168. <programlisting language="php"><![CDATA[
  169. $paginator = Zend_Paginator::factory($someData);
  170. Zend_Paginator::setCache($cache);
  171. // извлечение некоторых элементов
  172. $items = $paginator->getCurrentItems();
  173. // весь кэш будет очищен:
  174. $paginator->setItemCountPerPage(2);
  175. ]]></programlisting>
  176. </para>
  177. <para>
  178. Можно также видеть данные в кэше и запрашивать их напрямую.
  179. Для этого может использоваться
  180. метод <methodname>getPageItemCache()</methodname>:
  181. </para>
  182. <para>
  183. <programlisting language="php"><![CDATA[
  184. $paginator = Zend_Paginator::factory($someData);
  185. $paginator->setItemCountPerPage(3);
  186. Zend_Paginator::setCache($cache);
  187. // извлечение некоторых элементов
  188. $items = $paginator->getCurrentItems();
  189. $otherItems = $paginator->getItemsPerPage(4);
  190. // просмотр сохраненных в кэше элементов в виде двухмерного массива:
  191. var_dump($paginator->getPageItemCache());
  192. ]]></programlisting>
  193. </para>
  194. </sect2>
  195. <sect2 id="zend.paginator.advanced.aggregator">
  196. <title>Интерфейс Zend_Paginator_AdapterAggregate</title>
  197. <para>
  198. В зависимости от разрабатываемого приложения может возникнуть
  199. потребность разбивать на страницы объекты, у которых внутренняя
  200. структура данных эквивалентна существующим адаптерам,
  201. но при этом вы не хотите нарушать инкапсуляцию для
  202. того, что предоставлять доступ к этим данным.
  203. В других случаях объект может участвовать в связи
  204. "имеет-адаптер" вместо связи "является-адаптером", которую
  205. предлагает <classname>Zend_Paginator_Adapter_Abstract</classname>.
  206. В этих случаях вы можете использовать интерфейс
  207. <classname>Zend_Paginator_AdapterAggregate</classname>,
  208. который по поведению значительно похож на интерфейс
  209. <classname>IteratorAggregate</classname> из расширения SPL.
  210. </para>
  211. <para>
  212. <programlisting language="php"><![CDATA[
  213. interface Zend_Paginator_AdapterAggregate
  214. {
  215. /**
  216. * Возвращайте из этого метода полностью сконфигурированный адаптер.
  217. *
  218. * @return Zend_Paginator_Adapter_Abstract
  219. */
  220. public function getPaginatorAdapter();
  221. }
  222. ]]></programlisting>
  223. </para>
  224. <para>
  225. Как видно из кода, интерфейс довольно небольшой и от вас ожидается
  226. только возврат экземпляра
  227. <classname>Zend_Paginator_Adapter_Abstract</classname>.
  228. Фабричный метод
  229. <methodname>Zend_Paginator::factory</methodname> и конструктор
  230. класса <classname>Zend_Paginator</classname> после этого распознают
  231. экземпляр <classname>Zend_Paginator_AdapterAggregate</classname>
  232. и обрабатывают его должным образом.
  233. </para>
  234. </sect2>
  235. </sect1>
  236. <!--
  237. vim:se ts=4 sw=4 et:
  238. -->