Постраничная навигация на сайте

15.07.2011

Очень часто бывает необходимость в создании постаничной навигации на сайте, например для новостей, статей, фотоальбомов, когда колличество записей стаёт очень большим и неудобным для чтения. В этой статье я расскажу о том, как создать простую и надёжную постраничную навигацию для уже написанного компонента на PHP.

Этапы создания постраничной навигации (пейджера)

  1. Смещение и ограничение, т.е. нормирование, вывода данных из модели (функции вывода данных нашего компонента).
  2. Формирование и вывод динамического меню, изменяющегося в зависимости от кол-ва информации на сайте, и от предела вывода информации на одной странице.
  3. Осуществление взаимодействия между нашим меню и выводом данных.
    1. На первом этапе нам нужно иметь возможность ограничивать вывод информации. Предположим в классе News нашего компенента есть метод _list(), который осуществляет выборку из таблицы базы данных всех новостей.

      Пример метода _list() не нормализующего вывод информации

      function _list()
      {
      	$query = 'SELECT * FROM `news` WHERE `status`>0 ORDER BY `id` DESC';
      	$res = $this->db->fetch_object($query);
      	return (isset($res[0]->id)) ?$res :NULL;
      }
      

      Формируется SQL-запрос в котором осуществляется выборка всех полей из таблицы news, в которых поле status больше нуля и упорядочивает строки по полю id в порядке убывания. После этого это запрос отправляются в базу данных, и анализируется данные, путём проверки содержиния в них объекта id в массиве с нулевым индексом (результат выпонения функции mysqli_fatch_object(), и при его наличии метод отдаёт этт данные ввиде массива объектов, в котором каждый элемент массива является строкой, а каждый объект является полем таблицы news.)

      Теперь добавим в метод _list() нормализацию вывода.

      Пример метода _list() осуществляющий нормализацию вывода информации

      function _list()
      {
      	$query = 'SELECT * FROM `news` WHERE `status`>0 ORDER BY `id` DESC';
      	$res = $this->db->fetch_object($query);
      	$this->count = count($res);
      	if (isset($res[0]->id) && (int)$this->limit > 0 && (int)$_REQUEST['step'] > 0)
      		$res = array_slice($res,((int)$_REQUEST['step']-1)*$this->limit,$this->limit);
      	return (isset($res[0]->id)) ?$res :NULL;
      }
      

      После получения данных из таблицы, счетаются элеметы массива, которые соответствуют кол-ву всех строк, взятых из таблицы news и сохраняются в свойство count. Затем проверяется установлено ли ограничение на вывод данных, хранящиеся в своестве limit и задан ли в элементе step суперглобального массива $_REQUEST шаг отображения страницы, т.е. номер страницы, которую нужно отобразить? В случае негативного ответа после проверки, являются ди данные массивом содержащим свойтво id, данные отдаются без изменения. Но в случае положительного ответа данные нормализуются по средством функции array_slice(array,int1,int2), которая делает выборку из массива array начиная с позиции int1 кол-во элементов int2. И возвращает новый полученный массив, начиная со страницы указанной в $_REQUEST['step'] в котором содержится кол-во строк, указанное в ограничении limit.

      Для отображения страницы используется метод pager(url), которому передаётся строковый параметр url к которому нужно добавить номер страницы, по средством GET-запроса.

      Пример метода pager(url) формирующий и выводящий динамическое меню.

      function pager($url)
      {
      	if ((int)$this->limit > 0 && $this->count > $this->limit)
      	{
      		$count_page = ((int)$this->limit > 0) ?ceil($this->count/$this->limit) :0;
      		$step_prev = ((int)$_REQUEST['step'] > 0) ?(int)$_REQUEST['step']-1 :0;
      		$step_prev = ((int)$step_prev > 1) ?'/'.$step_prev :NULL;
      		echo '<div style="clear:both;" id="nav_page"><ul><li class="arrow"><a href="/',$url,$step_prev,'">&laquo;</a></li>';
      
      		for($i=1; ($i-1)<$count_page; ++$i)
      		{
      			$current = ((int)$_REQUEST['step'] == $i) ?'class="current_nav" ' :NULL;
      			$step = ($i > 1) ?'/'.$i :NULL;
      			echo '<li><a ',$current,'href="/',$url,$step,'">',$i,'</a></li>';
      		}
      
      		$step_next = ((int)$_REQUEST['step'] < $count_page) ?(int)$_REQUEST['step']+1 :$count_page;
      		$step_next = ((int)$step_next > 1) ?'/'.$step_next :NULL;
      		echo '<li class="arrow"><a href="/',$url,$step_next,'">&raquo;</a></li></ul></div>';
      		return $count_page;
      	}
      	else return NULL;
      }
      

      Происходит проверка установлено ли ограничение в свойстве limit и если установлено то больше ли оно чем кол-во строк, сохранёных ранее в свойстве count? В случае негативного ответа, метод возвращает пустоту. Если условия выполняются. то метод формирует динамическое меню, состоящие из стрелок переключения на одну страницу больше или меньше и цифровых ссылок, соответствующим каждым страницам данных, при нажатии на которые через метод GET информация о текущей странице попадает в метод _list() и изменяет вывод информации.

      Пример вызова методов _list() и pager(url) осуществляющих постраничную навигацию.

      $res = $obj->_list();
      ...............................
      Код обработки данных о новостях
      ...............................
      $obj->pager($_REQUEST['view'].'/'.$obj->id_alias((int)$_REQUEST['id']).'.html');
      

      Значала вызывается метод _list(), нормализирующий вывод данных, а потом вызывается метод pager(url), формирующий и отображающий меню постраничной навигации.

Последнее в нашем блоге