Lección 16: Paginador

Un día entras en Amazon y pulsas en la lupa para buscar calcetines. Al apretar Enter te redirecciona a una página donde están todos los calcetines del mundo, unos 23.000. Todos en columna, uno encima del otro donde casi el scroll del navegador es tan fino que apenas es usable. ¿Te imaginas lo incómodo de este escenario? Por ello mismo se crearon los paginadores, o botones para pasar entre resultados. Mecanismos para avanzar por bloques de elementos con un número bien definido. Para construir este sistema necesitaremos un poco de ingenio espolvoreado con un viejo truco matemático.

Tomamos de partida los 10 primeros personajes, ordenados alfabéticamente, de juegos de tronos como “base de datos”.

$personajes = [
  'Abelar Hightower',
  'Addam Frey',
  'Addam',
  'Addam Osgrey',
  'Addam Marbrand',
  'Addison Hill',
  'Aegon Blackfyre',
  'Addam Velaryon',
  'Aegon Frey (son of Aenys)',
  'Aegon Frey (son of Stevron)'
];

Nuestro objetivo será mostrar únicamente 3 resultados por página, a continuación iremos completando con más funciones.

Iniciamos con la primera página. Definimos el Limite de resultados y la página donde nos encontramos. Luego imprimimos con foreach.

<?php
// Constante con el número de resultados por página: 3
define('LIMITE_RESULTADOS', 3);
// Página donde nos encontramos. Si existe un GET con el nombre 'página' se guarda sino será 1.
$paginaActual = 1; 
// Crea un nuevo array con los personajes a mostrar en la página
$personajesPagina = array_splice($personajes, ($paginaActual - 1) * LIMITE_RESULTADOS, LIMITE_RESULTADOS);
?>
<html>
    <body>
        <?php foreach ($personajesPagina as $personaje): ?>
        <div>
            <h1><?= $personaje ?></h1>
            <hr>
        </div>
        <?php endforeach; ?>
    </body>
</html>

Genera lo que necesitamos, los 3 primeros nombres.

<html>
    <body>
        <div>
            <h1>Abelar Hightower</h1>
            <hr>
        </div>
        <div>
            <h1>Addam Frey</h1>
            <hr>
        </div>
        <div>
            <h1>Addam</h1>
            <hr>
        </div>
    </body>
</html>

Hemos roto el array de personajes en otro más pequeño, con ayuda de array_splice.

array_splice([array], [posicion donde empezar], [longitud del corte]);

Nuestro array_splice luce de la siguiente manera:

array_splice($personajes, ($paginaActual - 1) * LIMITE_RESULTADOS, LIMITE_RESULTADOS);
<?php
//======================================================================
// Variables
//======================================================================
$personajes = [
  'Abelar Hightower',
  'Addam Frey',
  'Addam',
  'Addam Osgrey',
  'Addam Marbrand',
  'Addison Hill',
  'Aegon Blackfyre',
  'Addam Velaryon',
  'Aegon Frey (son of Aenys)',
  'Aegon Frey (son of Stevron)'
];
// Constante con el número de resultados por página: 3
define('LIMITE_RESULTADOS', 3);
// Página donde nos encontramos. Si existe un GET con el nombre 'página' se guarda sino será 1.
$paginaActual = isset($_REQUEST['pagina']) ? $_REQUEST['pagina'] : 1; 
// Crea un nuevo array con los personajes a mostrar en la página
$personajesPagina = array_splice($personajes, ($paginaActual - 1) * LIMITE_RESULTADOS, LIMITE_RESULTADOS);
// Guardo un Truo o False si nos encontramos en la primera página: ¿La página actual es la primera?
$esPrimera = $paginaActual == 1;
// Guardo un Truo o False si nos encontramos en la última página: ¿La página actual es la última?
$esUltima = ceil(count($personajes) / LIMITE_RESULTADOS) == $paginaActual;

//======================================================================
// HTML
//======================================================================
?>
<html>
    <body>
        <!-- Bucle que dibuja todos los personajes -->
        <?php foreach ( $personajesPagina as $personaje): ?>
        <div>
            <h1><?= $personaje ?></h1>
            <hr>
        </div>
        <?php endforeach; ?>
        <!-- Botón para retroceder -->
        <?php if (!$esPrimera): ?>
        <a href="paginador.php?pagina=<?= $paginaActual - 1 ?>">Anterior</a>
        <?php endif; ?>
        <!-- Botón para avanzar -->
        <?php if (!$esUltima): ?>
        <a href="paginador.php?pagina=<?= $paginaActual + 1 ?>">Siguiente</a>
        <?php endif; ?>
    </body>
</html>