Los resultados salen paginados desde la base de datos con una consulta como la siguiente:
SELECT * FROM film ORDER BY film_id desc LIMIT 10 OFFSET 0
Esta consulta devuelve 10 registros (limit 10) empezando por el principio (offset 0). Si quereis saber mas como funciona la paginación en SQL podéis mirar este artículo: Paginación de registros desde MySql donde lo explico en detalle.
Cuando recogemos los resultados de la consulta anterior en PHP lo que hay que hacer es mostrarlos en una tabla y calcular las botones de dirección como estos:
y calcular los valores para avanzar y retroceder en cada página mostrando los resultados correspondientes.
Para realizar esto crearemos una clase que devolverá el cuadro completo con los cálculos ya realizados. Si queréis echarle un vistazo a la clase
Vamos a ir por pasos:
Primer paso:
Definir la url de navegación entre páginas. La url tendrá de la siguiente forma:http://paginacion.local/index.php?page=10-0-1
Los parámetros los pasamos por el método GET ( page=10-0-1 ) y corresponden a:- 10 - Limit, Número de registros por página
- 0 - Offset, desde donde se empieza a coger registros (0 desde el principio)
- 1 - Número de página en la que estamos actualmente.
Segundo paso:
Una vez tenemos separados los parámetros hacemos la consulta a la base de datos para obtener los registros que necesitamos, la consulta devuelve los registros ya paginados, utilizando la que he puesto arriba.Después calculamos el número total de páginas y creamos un array con los datos que necesitamos para calcular la paginación.
Este array contendrá los siguientes elementos:
'refer_uri' => 'index.php',
'total_pages' => $pages,
'actual_page' => $actual_page,
'increase' => 3,
'decrease => 3,
'offset' => $offset,
'limit' => $limit,
- refer_uri, es la página por la que se está navegando, en este ejemplo index
- total_pages, numero de paginas que hay, calculo que hemos realizado anteriormente.
- actual_page, página actual en que nos encontramos
- increase y decrease, nos indicarán los números que van después de la página actual y antes.
- Offset, puntero desde donde se empiezan a coger registros en la base de datos
- Limit, número de registros a devolver en la consulta
# Si accedemos por primera vez y no hay parametros redirigimos a la misma ULR con parametros
if ( !isset($_GET['page']))
{
header( "location: http://" . $_SERVER['SERVER_NAME'] . ":" . $_SERVER['SERVER_PORT'] . "?page=" . LIMIT . "-0-1");
}
$params = explode( "-", $_GET['page']);
$limit = $params[0];
$offset = $params[1];
$actual_page = $params[2];
# Obenemos los datos de configuración para conectarse a al base de datos
# Y nos conectamos
$_config = ConfigClass::get("config.database")['sakila'];
PDOManager::Connection( $_config);
# Obrenemos los regisros de la base de datos ya paginados con el limit y Offset que
# viene por parametros
$film = new FilmModel();
$rows = $film->GetFilms($limit, $offset);
# Calculamos el numero de paginas que salen dividiendo el total de registros por los
# registros que se muestran por pantalla.
$pages = ceil($rows['count'] / $limit);
# Seteamos las variables que necesita la clase CustomPaging para calcular la pagina actual,
# siguiente, anterior, ultima y primera, asi como los numeros que siguen.
$paging = [
'refer_uri' => 'index.php',
'total_pages' => $pages,
'actual_page' => $actual_page,
'increase' => 3, # Number of pages before the current one
'decrease' => 3, # Number of pages after the current one
'offset' => $offset,
'limit' => $limit,
];
# Cerramos conexión con la base de datos
PDOManager::Close();
Tercer paso:
Por último nos queda crear la botonera y los enlaces a las páginas de navegación. Para esto he creado una función que devuelve el html completo pasando el array anterior.Como veréis el código es bastante explicativo y básicamente lo que realiza son cálculos, sumas y restas, para calcular el Offset y la página en la que estamos actualmente.
La clase que calcula el cuadro de paginación podéis verla en Github CustomPaging.php
Una vez vista la paginación voy a explicar como he estructurado el proyecto.
Estructura de directorios:
- config, ficheros de configuración
- lib, librerías que se utilizan en todos los proyectos:
- ConfigClass, es una clase para leer ficheros de configuración, si quereis saber mas leer este artículo: Clase para leer ficheros de configuración en PHP
- CustomErrorLog, clase para capturar los errores de PHP, Clase para guardar errores en PHP
- PDOManager, clase para ejecutar consultas contra MySql, postgreSQL, utiliza PDO. Aunque aquí se llama de otra forma es básicamente la misma PDO y PHP, clase de acceso a datos - PDOClass.php
- logs, directorio donde la clase CustomErrorLog guarda los logs
- models, directorio para guardar las clases que acceden a base de datos
- modules, aqui pongo la lógica de desarrollo y es donde esta la clase que pagina CustomPaging.php
- public, directorio que se enlaza en apache o nginx y punto de entrada de la aplicación
define( "LIMIT", 10);
function debug( $var)
{
$debug = debug_backtrace();
echo "" . $debug[0]['file']." ".$debug[0]['line']."
";
print_r($var);
echo "
" . "
";
}
include dirname( dirname(__FILE__)) . "/lib/ConfigClass.php";
include dirname( dirname(__FILE__)) . "/lib/CustomErrorLog.php";
include dirname( dirname(__FILE__)) . "/lib/PDOManager.php";
include dirname( dirname(__FILE__)) . "/models/FilmModel.php";
include dirname( dirname(__FILE__)) . "/modules/CustomPaging.php";
include dirname( dirname(__FILE__)) . "/modules/Pagination.php";
Nota a parte, la clase debug es para formatear los arrays por pantalla y decir que fichero php y linea se muestra por pantalla
Todo el código está en: https://github.com/depruebas/php-native-sql-pagination
Para probarlo poneros en el directorio public y ejecutar el servidor de PHP
php -S 127.0.0.1:8000
y en http://127.0.0.1:8000/index.php?page=10-0-1 podréis probarlo.Y esto es todo amigos, feliz programming!!
Saludos
Alex
También puede interesarte:
Configurar Laravel Sail para utilizar un MySql externo existente |
||