Page navigation on the site

15.07.2011

Very often there is a need to create page-by-page navigation on the site, for example, for news, articles, photo albums, when the number of entries becomes very large and inconvenient to read. In this article, I will talk about how to create a simple and reliable pagination for an already written PHP component.

Steps to create a page navigation (pager)

  1. Offset and constraint, i.e. normalization, data output from the model (data output function of our component).
  2. Formation and display of a dynamic menu that changes depending on the amount of information on the site, and on the limit of information output on one page.
  3. Implementing the interaction between our menu and data output.
    1. At the first stage, we need to be able to limit the output of information. Suppose our component's News class has a _list() method that fetches all news from the database table.

      An example of the _list() method that does not normalize the output of information

      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;
      }
      

      An SQL query is generated in which a selection of all fields from the news table in which the status field is greater than zero is performed and arranges the rows by the id field in descending order. After that, this query is sent to the database, and the data is analyzed by checking the content of the id object in the array with a zero index (the result of executing the mysqli_fatch_object () function, and if it is available, the method returns this data in the form of an array of objects, in which each element of the array is a string, and each object is a field in the news table.)

      Now let's add output normalization to the _list() method.

      An example of the _list() method that normalizes the output of information

      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;
      }
      

      After receiving data from the table, the array elements are counted, which correspond to the number of all rows taken from the news table and stored in the count property. Then it is checked whether the restriction on the output of the data stored in the limit property is set and whether the page rendering step is set in the step element of the $_REQUEST superglobal array, i.e. page number to display? In case of a negative answer after checking, the data is an array containing the id property, the data is returned without change. But in the case of a positive answer, the data is normalized by means of the array_slice(array, int1, int2) function, which makes a selection from the array array starting from the int1 position, the number of int2 elements. And returns the new resulting array, starting from the page specified in $_REQUEST['step'] which contains the number of lines specified in the limit constraint.

      To display the page, the pager(url) method is used, to which the url string parameter is passed, to which the page number must be added, using a GET request.

      An example of the pager(url) method that forms and displays a dynamic menu.

      functionpager($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;
      }
      

      Is there a check whether the limit is set in the limit property, and if it is set, is it greater than the number of rows stored earlier in the count property? In case of a negative answer, the method returns void. If the conditions are met. then the method generates a dynamic menu consisting of arrows for switching one page more or less and digital links corresponding to each data page, when clicked through the GET method, information about the current page enters the _list() method and changes the output of information.

      An example of calling the _list() and pager(url) methods that perform pagination.

      $res = $obj->_list();
      ...............................
      News processing code
      ...............................
      $obj->pager($_REQUEST['view'].'/'.$obj->id_alias((int)$_REQUEST['id']).'.html');
      

      First, the _list() method is called, which normalizes the data output, and then the pager(url) method is called, which forms and displays the pagination menu.

Last in our blog

Internet Marketing
04.11.2019