Paginación usando LIMIT.

Resumen.

Ya hemos visto como mostrar en pantalla los datos almacenados en nuestras tablas MySQL, y mas de uno habréis apreciado que con el método expuesto se muestran todos los resultados existentes, si la tabla es pequeña, digamos menos de 50 registros, es asumible ese método, pero si la tabla contiene cientos de resultados, y no digamos miles, debemos dividir los resultados en diferentes páginas, lo que se denomina, paginar o paginación.

Artículo.

Existen muchos métodos para paginar los resultados de una consulta, cada uno tiene sus virtudes y sus defectos. En este artículo vamos a ver como crear un sencillo sistema de paginación, de la forma mas sencilla posible, usando un mínimo de código, para lo cual nos vamos a valer de la cláusula LIMIT de MySQL, que como sabemos puede recibir uno o dos parámetros.

Cuando LIMIT lleva un solo parámetro (LIMIT 10, por ejemplo), nuestra consulta solo mostrará 10 registros. Cuando LIMIT lleva dos parámetros (LIMIT 10,5), la consulta mostrará 5 registros a partiendo del registro número 10, en sentido ascendente o descendente según el valor de la cláusula ORDER (que puede tomar valores ASC y DESC). La consulta podría quedar de la siguiente manera:

SELECT * FROM $tb1 WHERE sexo = '2' ORDER BY usuario ASC LIMIT 0, 10


Con esta consulta seleccionamos a las mujeres (recordemos que le asignamos el valor 2), ordenamos el listado por orden alfabético y mostramos 10 registros que comienzan en la key 0, recordemos que en los arrays el valor de la primera key es 0 (OJO, no confundir la key o clave del array con el id de registro de cada usuario).

Con esa estructura de consulta ya tenemos la esencia de nuestro sistema de paginación, el problema radica en como hacemos que cambien los parámetros de LIMIT, la forma mas sencilla es pasar esos valores por URL mediante un link.

<a href=\"paginador.php?rg=10\">Siguiente</a>


De esta forma la consulta quedaría de la siguiente manera:

SELECT * FROM $tb1 WHERE sexo = '2' ORDER BY usuario ASC LIMIT 10, 10


El procedimiento seria el mismo para los sucesivos grupos de resultados, veamos ahora como podemos hacer todo esto.

<?php include('archivos/func_conexionBD.php'); include('archivos/funcion_orden_fecha.php'); // Desarrollado por ArtesaniaWeb.Es // Paginación de una tabla MySQL mediante LIMIT // Variables a modificar $reg_pagi = 10; // Registros por pagina $SubConsul = null; // Ej: "WHERE sexo = '2' ORDER BY usuario ASC" $Tabla = $tb1; $Conex_BD = ConectaBD(); // Contamos TODOS los resultados que se paginaran $_Paginacion_SQL = "SELECT * FROM $Tabla $SubConsul"; $_Paginacion = mysqli_query($Conex_BD, $_Paginacion_SQL); $N_Paginacion = mysqli_num_rows($_Paginacion); // Recibimos y validamos la variable de registros que nos permitira la paginacion @$rg = $_GET['rg']; // Registro a partir del cual mostraremos los resultados $volver = '<script> window.location="javascript:history.go(-1)"; </script>'; // Validamos la variable $rg para que solo puedan entrar valores numericos enteros if (!preg_match('/^[[:digit:]]{0,8}$/',$rg)) die ($volver); if ($rg > 0){ // Si recibimos un valor por la variable $rg ejecutamos esta consulta $Paginando = "SELECT * FROM $Tabla $SubConsul LIMIT $rg,$reg_pagi"; }else{ // Si NO recibimos un valor por la variable $rg ejecutamos esta consulta $Paginando = "SELECT * FROM $Tabla $SubConsul LIMIT 0,$reg_pagi"; } $R_Paginando = mysqli_query($Conex_BD, $Paginando); $numero_registros = mysqli_num_rows($R_Paginando); // Contamos registros en paginacion echo '<div align="center"><table border="1" width="80%"> <tr> <td><b>Id</b></td> <td><b>Usuario</b></td> <td><b>Email</b></td> <td><b>Fecha</b></td> </tr>'; while($registro = mysqli_fetch_array($R_Paginando)){ echo "<tr> <td>".$registro['id']."</td> <td><a href=\"ficha_usuario.php?us=".$registro['usuario']."\" title=\"Ver ficha del usuario\">".$registro['usuario']."</a></td> <td>".$registro['email']."</td> <td>".Forma_Fecha($registro['f_regis'])[5]."</td> </tr>"; } echo '</table></div>'; DesconectaBD($Conex_BD); // ----------------------------- Pagina anterior $prim_reg_ant = abs($reg_pagi - $rg); if ($rg <> 0){ $pag_anterior = "<a href=\"".$_SERVER['PHP_SELF']."?rg=$prim_reg_ant\">Anterior</a>"; } // ----------------------------- Pagina siguiente $prim_reg_sigu = $reg_pagi + $rg; if ($rg < $N_Paginacion - ($reg_pagi - 1)){ $pag_siguiente = "<a href=\"".$_SERVER['PHP_SELF']."?rg=$prim_reg_sigu\">Siguiente</a>"; } // ----------------------------- // Creamos las paginas de navegacion $Sep = '|'; // Separador de los enlaces $n_pagi = ceil($N_Paginacion / $reg_pagi); // Calculamos el numero de paginas $n_ultima = $N_Paginacion - 1; // Valor de $rg para la ultima pagina // Si estamos en la ultima pagina, no se mostrará el enlace a la ultima paginacion if($rg == $n_ultima){ $ultima = null; }else{ $ultima = "<a href=\"".$_SERVER['PHP_SELF']."?rg=$n_ultima\">Última</a>"; } // Creamos las barras de navegacion if($rg == 0){ // Si estamos en la primera pagina, no mostramos los enlaces a primera pagina ni anterior $pagi_navegacion = "$pag_siguiente $Sep $ultima"; }else{ @$pagi_navegacion = "<a href=\"".$_SERVER['PHP_SELF']."\">Inicio</a> $Sep $pag_anterior $Sep $pag_siguiente $Sep $ultima"; } // Si se realiza la paginacion, mostramos la barra de navegacion if($N_Paginacion > $reg_pagi){ // No hacemos nada }else{ $pagi_navegacion = null; } // Mostramos el ecuento de resultados, y si es preciso, la barra de nagegacion echo "<p align=\"right\">$numero_registros resultados<br /> en $n_pagi paginas de $N_Paginacion totales</p> <p align=\"center\">$pagi_navegacion</p>"; ?>

Vamos ahora a analizar este código, y lo primero que hacemos es cargar la función de conexión a base de datos y la de ordenar fecha.

Seguidamente declaramos las variables que precisamos para la paginación. La variable $reg_pagi nos dice el número de registros que queremos en cada página, en este caso, 10. la variable $SubConsul la hemos creado para que sea fácil la configuración del paginador, ya que en las tres consultas existentes llevara el mismo valor. En este caso esta declarada como null, ya que vamos a consultar todos los registros, si quisiéramos por ejemplo filtrar por sexo y asignar un orden le dariamos el siguiente valor WHERE sexo = '2' ORDER BY usuario ASC. De esta forma, este criterio iría a las tres consultas sin tenerlas que modificar una a una. Por ultimo, y por el mismo motivo, la variable $Tabla contiene el nombre de la tabla que vamos a consultar en las tres posibles consultas.

Una vez hecho esto, contamos el total de registros que vamos a paginar y recibimos mediante la variable $rg que registros se mostrarán y la validamos.

Según el valor que toma la variable $rg ejecutamos una consulta con la cláusula LIMIT, donde si su valor es diferente de 0 el inicio de LIMIT toma el valor de esta variable. En caso de que el valor sea 0, en la misma consulta introducimos el 0 como valor de inicio de LIMIT. Por lo demás, la consulta se ejecuta tal y como vimos en este artículo.

Tras el bucle while creamos los enlaces para pasar los valores de paginación que precisa la cláusula LIMIT. Calculamos los valores de las páginas según los resultados existentes y el número de resultados que mostraremos en cada página. Mediante $_SERVER['PHP_SELF'] capturamos el nombre que le hemos dado a nuestra página y pasamos los valores de $rg por URL.

Para finalizar, mostramos el recuento de todos los resultados, el número de resultados de cada página, que en la ultima página de paginación puede ser diferente al de resultados por página asignados, es decir, si mostramos 10 resultados por página y tenemos 106 resultados, la ultima página solo mostrará 6 resultados, como resulta obvio.

Y con esto cerramos este artículo dedicado a la paginación de resultados, este método lo he desarrollado yo mismo de manera un tanto rápida, funciona correctamente y si el número de registros no es demasiado elevado, resulta practico. Si el número de resultados fuera muy elevado, por ejemplo 1200 resultados paginados de 10 en 10, tendríamos muchas páginas por las que seria preciso avanzar una a una, lo que según los casos, podría resultar pesado, pero esto ya es una cuestión del uso que cada cual vaya a desempeñar.

Tags: LIMIT || paginación || dividir || mysqli_num_rows || contar registros

Comentarios.

Sin comentarios, publica el tuyo.