Paginar los resultados de una consulta en PHP (II)

En este artículo voy a recoger dos de las sugerencias recibidas a partir de la publicación del anterior. Una consiste en mejorar la velocidad empleando una consulta en lugar de dos,

Mostrar los registros adecuados con una sola consulta

Para poder soportar paginación debemos, primero, decidir cuantos registros presentamos por página (por ejemplo, 10) y recibir el número de página que debemos presentar. En esta ocasión utilizaremos una sola consulta donde obtendremos todos los registros. De ahi escogeremos sólo los registros que queramos presentar y averiguaremos cuantos hay en total. Obtendremos el siguiente código, si empleamos el ejemplo de la tabla clientes:

<html> 
<body> 
<?php 
$link = mysql_connect("localhost", "nobody"); 
mysql_select_db("mydb", $link); 
if (!isset($pag)) $pag = 1; // Por defecto, pagina 1
$tampag = 10;
$reg1 = ($pag-1) * $tampag;
$result = mysql_query("SELECT nombre, apellidos FROM clientes", $link); 
$total = mysql_num_rows($result);
if (mysql_num_rows($result)){ 
  echo "<table border = '1'> 
"; 
  echo "<tr><td>Nombre</td><td>Apellidos</td></tr> 
";
  for ($i=$reg1; $i<min($reg1+$tampag, $total); $i++) {
    mysql_data_seek($result, $i);
    $row = mysql_fetch_array($result);
    echo "<tr><td>".$row["nombre"].
      "</td><td>".$row["email"]."</td></tr> 
"; 
  }
  echo "</table> 
"; 
}
else
  echo "¡ No se ha encontrado ningún registro !";
?>

Para obtener el total de registros recuperamos todos y utilizamos la función mysql_num_rows que devuelve el número de filas del resultado de una consulta. Luego, para escribir sólo los registros que necesitamos, empleamos un bucle for que itera desde el primer registro a obtener hasta la menor de las dos siguientes cantidades:

  • El primer registro más el número de registros por página
  • El número total de registros

De este modo nos aseguramos de que funcione correctamente también en la última página, que en la mayoría de los casos tendrá menos registros que las demás. Luego, para acceder al registro número $i utilizamos la función mysql_data_seek, que mueve el puntero del recordset (conjunto de resultados de una consulta) a la posición que le indicamos, que en nuestro caso será $i.

Limitar los enlaces a otras páginas

A la función abstracta que creamos en el artículo pasado le vamos a añadir un nuevo parámetro, opcional, que indicará el número máximo de enlaces que quiere presentar a la vez. La salida que proporcionará esta función será similar a la de Google, en el que existe un número máximo de páginas a presentar, pero si estamos en uno de los dos extremos, sólo presentará la mitad.

Las novedades están destacadas:

/******************************************************/
/* Funcion paginar
 * actual:          Pagina actual
 * total:           Total de registros
 * por_pagina:      Registros por pagina
 * enlace:          Texto del enlace
 * maxpags:         El máximo de páginas a presentar simultáneamente (opcional)
 * Devuelve un texto que representa la paginacion
 */
function paginar($actual, $total, $por_pagina, $enlace, $maxpags=0) {
  $total_paginas = ceil($total/$por_pagina);
  $anterior = $actual - 1;
  $posterior = $actual + 1;
  $minimo = $maxpags ? max(1, $actual-ceil($maxpags/2)): 1;
  $maximo = $maxpags ? min($total_paginas, $actual+floor($maxpags/2)): $total_paginas;
  if ($actual>1)
    $texto = "<a href="$enlace$anterior">&laquo;</a> ";
  else
    $texto = "<b>&laquo;</b> ";
  if ($minimo!=1) $texto.= "... ";
  for ($i=$minimo; $i<$actual; $i++)
    $texto .= "<a href="$enlace$i">$i</a> ";
  $texto .= "<b>$actual</b> ";
  for ($i=$actual+1; $i<=$maximo; $i++)
    $texto .= "<a href="$enlace$i">$i</a> ";
  if ($maximo!=$total_paginas) $texto.= "... ";
  if ($actual<$total_paginas)
    $texto .= "<a href="$enlace$posterior">&raquo;</a>";
  else
    $texto .= "<b>&raquo;</b>";
  return $texto;
}

La principal novedad es que, a la hora de escribir las páginas que están antes y después de la que estamos viendo no partimos de los extremos (1 y $total_paginas) sino de unas variables $minimo y $maximo) que contienen el menor de estos dos valores:

  • La distancia entre la página actual y el extremo.
  • El máximo de páginas a presentar simultáneamente dividido por dos.

Por otro lado, en los casos en que $minimo fuera mayor que 1 o $maximo menor que el total de página, presentaremos unos puntos suspensivos indicando este hecho.

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
ARTÍCULO ANTERIOR

SIGUIENTE ARTÍCULO

¡SÉ EL PRIMERO EN COMENTAR!
Conéctate o Regístrate para dejar tu comentario.