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