Введение в Zend Framework

 Learning Zend Framework

appendix

 Zend Framework Reference


  • Zend_Gdata
  • Zend_Http
  • Zend_InfoCard
  • Zend_Json
  • Zend_Layout
  • Zend_Ldap
  • Zend_Loader
  • Zend_Locale
  • Zend_Log
  • Zend_Mail
  • Zend_Markup
  • Zend_Measure
  • Zend_Memory
  • Zend_Mime
  • Zend_Navigation
  • Zend_Oauth
  • Zend_OpenId
  • Zend_Paginator
  • Zend_Pdf
  • Zend_ProgressBar
  • Zend_Queue
  • Zend_Reflection
  • Zend_Registry
  • Zend_Rest

  • Zend_Search_Lucene
  • Zend_Serializer
  • Zend_Server
  • Zend_Service
  • Zend_Session
  • Zend_Soap
  • Zend_Tag
  • Zend_Test
  • Zend_Text
  • Zend_TimeSync
  • Zend_Tool
  • Zend_Tool_Framework
  • Zend_Tool_Project
  • Zend_Translate
  • Zend_Uri
  • Zend_Validate
  • Zend_Version
  • Zend_View
  • Zend_Wildfire
  • Zend_XmlRpc
  • ZendX_Console_Process_Unix
  • ZendX_JQuery
  • Ttranslation 27.4% Update 2010-11-28 - Revision 23238 - Version ZF 1.11.x

    53.2. Использование

    53.2.1. Разбиение наборов данных на страницы

    Для разбиения наборов данных на страницы Zend_Paginator должен иметь обобщенный доступ к этим данным. Поэтому доступ к данным осуществляется через адаптеры к источникам данных. В поставку Zend Framework по умолчанию входят несколько адаптеров:

    Таблица 53.1. Адаптеры для Zend_Paginator

    Адаптер Описание
    Array Использует PHP-массив
    DbSelect Использует экземпляр Zend_Db_Select, который будет возвращать массив
    DbTableSelect Использует экземпляр Zend_Db_Table_Select, который будет возвращать объект Zend_Db_Table_Rowset_Abstract. Это дает возможность получить такую дополнительную информацию, как, например, имена столбцов.
    Iterator Использует экземпляр Iterator
    Null Не использовать Zend_Paginator для разбиения на страницы. Но и в этом случае вы можете воспользоваться возможностями постраничной навигации.

    [Замечание] Замечание

    Вместо извлечения всех строк, соответствующих данному запросу, адаптеры DbSelect and DbTableSelect извлекают только тот объем данных, который необходим для отображения текущей страницы.

    Поэтому для определения общего количества соответствующих запросу строк динамически генерируется второй запрос. Но вы можете сами предоставить адаптеру количество строк либо запрос для его определения. См. метод setRowCount() в адаптере DbSelect для получения более подробной информации.

    При создании экземпляра класса Zend_Paginator следует передавать адаптер его конструктору:

    $paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Array($array));

    Для удобства вы можете воспользоваться фабричным методом factory() для получения адаптеров, входящих в поставку Zend Framework:

    $paginator Zend_Paginator::factory($array);
    [Замечание] Замечание

    В случае использования адаптера Null вы должны передавать его конструктору количество элементов вместо набора данных.

    Несмотря на то, что на этом этапе экземпляр формально уже пригоден к использованию, на практике вы должны будете еще передавать номер страницы, запрошенный пользователем, чтобы он мог просматривать данные:

    $paginator->setCurrentPageNumber($page);

    Наиболее простым способом отслеживания номера страницы является использование URL. Мы рекомендуем использовать для этого совместимый с Zend_Controller_Router_Interface маршрутизатор, но это не является обязательным требованием.

    Ниже приведен пример маршрута, который можно использовать в конфигурационном файле INI:

    routes.example.route articles/:articleName/:page
    routes
    .example.defaults.controller articles
    routes
    .example.defaults.action view
    routes
    .example.defaults.page 1
    routes
    .example.reqs.articleName = \w+
    routes.example.reqs.page = \d+

    Используя этот маршрут и MVC-компоненты Zend Framework-а, вы можете устанавливать номер текущей страницы следующим образом:

    $paginator->setCurrentPageNumber($this->_getParam('page'));

    Есть также другие опции, о них читайте в разделе Конфигурация.

    После этого нужно присвоить экземпляр Zend_Paginator переменной вида. Если используется Zend_View с помощником действий ViewRenderer, то для этого подходит следующий код:

    $this->view->paginator $paginator;

    53.2.2. Адаптеры DbSelect и DbTableSelect

    Хотя большинство адаптеров довольно просто в использовании, адаптеры баз данных требуют дополнительных пояснений насчет извлечения данных и подсчета количества строк.

    При использовании адаптеры DbSelect и DbTableSelect нет необходимости самостоятельно извлекать данные. Оба адаптера сами выполняют извлечение данных и подсчет общего количества страниц. Если полученные результаты выборки требуют дополнительной обработки, то адаптер может быть расширен с переопределением метода getItems().

    Эти адаптеры не извлекают все записи из базы данных для того, чтобы посчитать их. Вместо этого адаптеры используют исходный запрос для получения соответствующего COUNT-запроса, этот запрос выполняется для получения общего количества строк. Таким образом, производится еще один дополнительный запрос к базе данных, но это во много раз быстрее, чем извлечение всего результата и использование count(), особенно в случае больших объемов данных.

    Адаптеры баз данных будут пытаться строить наиболее эффективный запрос, который будет выполняться практически на всех современных СУРБД. Но в зависимости от используемой базы данных или даже выбранной структуры могут быть более эффективные пути получения количества строк. На этот случай адаптеры баз данных дают возможность устанавливать свой COUNT-запрос. Например, если вы фиксируете количество постов в блоге в отдельной таблице, то можете достичь более быстрого получения их количества, написав следующий код:

    $adapter = new Zend_Paginator_Adapter_DbSelect($db->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);

    Этот подход может не дать большого выигрыша в производительности в случае небольшого объема данных или простых запросов на извлечение. Однако в случае сложных запросов и больших объемов данных подобный подход может дать значительный выигрыш в производительности.

    53.2.3. Рендеринг страниц через скрипты видов

    Для визуализации элементов страницы (если вы используете для этого Zend_Paginator) и отображения постраничной навигации используется скрипт вида.

    Поскольку Zend_Paginator реализует SPL-интерфейс IteratorAggregate, то обход элементов и их отображение производится элементарно.

    <html>
    <
    body>
    <
    h1>Example</h1>
    <?
    php if (count($this->paginator)): ?>
    <ul>
    <?php foreach ($this->paginator as $item): ?>
      <li><?php echo $item?></li>
    <?php endforeach; ?>
    </ul>
    <?php endif; ?>

    <?php echo $this->paginationControl($this->paginator,
                                        
    'Sliding',
                                        
    'my_pagination_control.phtml'); ?>
    </body>
    </html>

    Обратите внимание, что в конце вызывается помощник вида. PaginationControl принимает экземпляр Zend_Paginator, стиль прокрутки, скрипт вида и массив дополнительных параметров.

    Второй и третий параметры очень важны. В то время как скрипт вида используется для определения внешнего вида постраничной навигации, стиль прокрутки определяет ее поведение. Предположим, скрипт вида отображает постраничную навигацию для результатов поиска следующего вида:

    Что должно происходить, если пользователь нажимает на ссылку "next" несколько раз? Действительно, тут может быть сколько угодно вариантов. Номер текущей страницы может оставаться в середине (как это реализовано, например, в Yahoo!) или перемещаться к концу ряда при каждом нажатии "next" и затем показываться снова с другого конца. Количество отображаемых номеров страниц может даже увеличиваться и уменьшаться, пока пользователь перемещается по ним (или "прокручивает" их), как это сделано в Google.

    Zend Framework предоставляет четыре стиля прокрутки:

    Таблица 53.2. Стили прокрутки для Zend_Paginator

    Стиль прокрутки Описание
    All Возвращает все страницы. Полезен для постраничной навигации в виде выпадающего списка с относительно небольшим количеством страниц. В этом случае предпочтительнее, чтобы в нем отображались все доступные страницы.
    Elastic Скроллинг в стиле Google, в котором количество отображаемых номеров страниц может увеличиваться и уменьшаться, пока пользователь перемещается по страницам.
    Jumping Пока пользователь листает страницы, номер текущей страницы перемещается к концу ряда и показывается снова в начале нового ряда.
    Sliding Скроллинг в стиле Yahoo!, в котором номер текущей страницы находится в середине ряда или настолько близко к нему, насколько это возможно. Этот стиль используется по умолчанию.

    Четвертый и последний параметр предназначается для ассоциативного массива дополнительных переменных, которые должны быть доступны в вашем скрипте вида (через $this). Например, эти значения могут включать в себя дополнительные параметры URL для подстановки в ссылки постраничной навигации.

    Установив используемые по умолчанию скрипт вида, стиль прокрутки и экземпляр вида, вы можете полностью исключить вызовы PaginationControl:

    Zend_Paginator::setDefaultScrollingStyle('Sliding');
    Zend_View_Helper_PaginationControl::setDefaultViewPartial(
        
    'my_pagination_control.phtml'
    );
    $paginator->setView($view);

    Если все эти значения установлены, то вы можете вывести постраничную навигацию в своем скрипте вида с помощью обычной конструкции echo:

    <?php echo $this->paginator?>
    [Замечание] Замечание

    Разумеется, можно использовать Zend_Paginator с другими шаблонизаторами. Например, со Smarty вы можете делать следующее:

    $smarty->assign('pages'$paginator->getPages());

    Вы можете затем обращаться к установленным значениям из шаблона, как в коде ниже:

    {$pages->pageCount}

    53.2.3.1. Примеры постраничной навигации

    Надеемся, следующие примеры помогут начать работать с Zend_Paginator:

    Постраничная навигация для результатов поиска:

    <!--
    Смhttp://developer.yahoo.com/ypatterns/pattern.php?pattern=searchpagination
    -->

    <?
    php if ($this->pageCount): ?>
    <div class="paginationControl">
    <!-- Ссылка на предыдущую страницу -->
    <?php if (isset($this->previous)): ?>
      <a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
        &amp;lt; Previous
      </a> |
    <?php else: ?>
      <span class="disabled">&amp;lt; Previous</span> |
    <?php endif; ?>

    <!-- Нумерованные ссылки на страницы -->
    <?php foreach ($this->pagesInRange as $page): ?>
      <?php if ($page != $this->current): ?>
        <a href="<?php echo $this->url(array('page' => $page)); ?>">
            <?php echo $page?>
        </a> |
      <?php else: ?>
        <?php echo $page?> |
      <?php endif; ?>
    <?php 
    endforeach; ?>

    <!-- Ссылка на следующую страницу -->
    <?php if (isset($this->next)): ?>
      <a href="<?php echo $this->url(array('page' => $this->next)); ?>">
        Next &amp;gt;
      </a>
    <?php else: ?>
      <span class="disabled">Next &amp;gt;</span>
    <?php endif; ?>
    </div>
    <?php endif; ?>

    Постраничная навигация для элементов:

    <!--
    Смhttp://developer.yahoo.com/ypatterns/pattern.php?pattern=itempagination
    -->

    <?
    php if ($this->pageCount): ?>
    <div class="paginationControl">
    <?php echo $this->firstItemNumber?> - <?php echo $this->lastItemNumber?>
    of <?php echo $this->totalItemCount?>

    <!-- Ссылка на первую страницу -->
    <?php if (isset($this->previous)): ?>
      <a href="<?php echo $this->url(array('page' => $this->first)); ?>">
        First
      </a> |
    <?php else: ?>
      <span class="disabled">First</span> |
    <?php endif; ?>

    <!-- Ссылка на предыдущую страницу -->
    <?php if (isset($this->previous)): ?>
      <a href="<?php echo $this->url(array('page' => $this->previous)); ?>">
        &amp;lt; Previous
      </a> |
    <?php else: ?>
      <span class="disabled">&amp;lt; Previous</span> |
    <?php endif; ?>

    <!-- Ссылка на следующую страницу -->
    <?php if (isset($this->next)): ?>
      <a href="<?php echo $this->url(array('page' => $this->next)); ?>">
        Next &amp;gt;
      </a> |
    <?php else: ?>
      <span class="disabled">Next &amp;gt;</span> |
    <?php endif; ?>

    <!-- Ссылка на последнюю страницу -->
    <?php if (isset($this->next)): ?>
      <a href="<?php echo $this->url(array('page' => $this->last)); ?>">
        Last
      </a>
    <?php else: ?>
      <span class="disabled">Last</span>
    <?php endif; ?>

    </div>
    <?php endif; ?>

    Постраничная навигация в виде выпадающего списка:

    <?php if ($this->pageCount): ?>
    <select id="paginationControl" size="1">
    <?php foreach ($this->pagesInRange as $page): ?>
      <?php $selected = ($page == $this->current) ? ' selected="selected"' ''?>
      <option value="<?php
            
    echo $this->url(array('page' => $page));?>"<?php echo $selected ?>>
        <?php echo $page?>
      </option>
    <?php endforeach; ?>
    </select>
    <?php endif; ?>

    <script type="text/javascript"
         src="http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.2/prototype.js">
    </script>
    <script type="text/javascript">
    $('paginationControl').observe('change', function() {
        window.location = this.options[this.selectedIndex].value;
    })
    </script>

    53.2.3.2. Список свойств

    Следующие опции доступны внутри скрипта вида для постраничной навигации:

    Таблица 53.3. Свойства, доступные в скрипте вида

    Свойство Тип Описание
    first integer Номер первой страницы (т.е. 1)
    firstItemNumber integer Действительный номер первого элемента на текущей странице
    firstPageInRange integer Первая страница в ряде, возвращенном текущим стилем прокрутки
    current integer Текущий номер страницы
    currentItemCount integer Количество элементов на текущей странице
    itemCountPerPage integer Максимальное количество отображаемых на странице элементов
    last integer Номер последней страницы
    lastItemNumber integer Действительный номер последнего элемента на текущей странице
    lastPageInRange integer Последняя страница в ряде, возвращенном текущим стилем прокрутки
    next integer Номер следующей страницы
    pageCount integer Общее количество страниц
    pagesInRange array Массив страниц, возвращенный текущим стилем прокрутки
    previous integer Номер предыдущей страницы
    totalItemCount integer Общее количество элементов

    digg delicious meneame google twitter technorati facebook

    Comments

    Loading...