pag(), paginación de resultados, objetos o paginas en PHP

Función pag()Algo que suele ser repetitivo en la mayoría de proyectos sobre todo si se usan bases de datos o listados de objetos, archivos, arrays… (cosa que en casi todos por no decir en todos se usa) es la paginación. La paginación como todos supongo que sabréis vale para dividir un conjunto de datos muy grande en porciones y poder navegar de esta forma entre los resultados. (si queréis ver un ejemplo solo tenéis que ir a la parte de abajo de google después de hacer una búsqueda).

Después de investigar como hacían otros este proceso me di cuenta que las soluciones mas comunes estaba solo orientadas dentro del PHP a mysql, y integraban no solo el manejo del menú de la pagina si no que a demás cortaban los objetos a mostrar o no mostrar.. cosa que no me interesaba. Yo solo quería el menú, y queria que pudiera valerme no solo para una base de datos, si no para un array o lo q fuera necesario.. :S.

La función que propongo hoy para solucionar esto es pag() la cual lo que hace es a partir de unos datos básicos introducidos como la pagina en la que se quiere estar, el numero de elementos a representar en el menú y el numero de elementos a visualizar por pagina devuelve un array con el contenido personalizado en numero de cada objeto, rango de objetos.. dando opciones a personalizar esta salida o mostrarlo con un simple enlace..

Para meternos en materia os pongo para que vale cada variable de la función por su orden:

  1. Pagina en la que se quiere estar o nombre de la variable GET o POST que va a contener el numero de pagina
  2. Total de objetos que hay en la lista a representar (total de resultados de una consulta, o de un array, o de archivos en una carpeta que queramos representar paginada)
  3. Numero de objetos que queremos que aparezcan en cada pagina
  4. Numero que indica cuantas paginas se ven en el menú generado
  5. Código HTML o texto que acompañará a cada numero.. si está vacio será representado por un enlace simple pero se puede completar con un texto HTML cualquiera. En este texto podemos insertar [p] en cada parte que deseemos que aparezca el numero de pagina. Si se inserta un array con dos textos, el primero corresponderá a los números de pagina normales y el segundo cuando la pagina sea la pagina que se está visitando.
  6. Si se desea incluir el botón “atrás” o “anterior” a partir de esta variable se puede escribir true para que aparezca un botón estándar, false para que no aparezca ningún botón o un texto HTML como en la anterior variable, en el que también se sustituirá [p] por el numero de pagina “anterior”. Si el menú esta situado en la primera pagina no se mostrara este botón.
  7. Idéntico funcionamiento al anterior. Esta variable establece si queremos mostrar el botón de “pagina siguiente”. Como en el anterior false o true lo activan o desactivan y un texto personalizado puede ser establecido como base, siendo sustituido [p]. (este botón no será mostrado si el menú está en el ultimo resultado.)
  8. Esta ultima variable de la función establece si se quiere mostrar un botón que lleva a la ultima pagina. Como en los anteriores, si se quiere activar el modo por defecto que incluye un enlace, solo hay que poner true, si se prefiere que no salga, false y si se quiere personalizar solo hay que poner el texto o código HTML con [p] en las zonas donde se quiere que se escriban el numero correspondiente.

Aquí va el código de la función:
[PHP]
function pag(
$pag_actual = 1, //pagina actual
$total_objetos = 60, //total de objetos a contar
$objetos_por_pagina = 5, //total de objetos por cada pagina
$objetos_por_menu = 5, //números que aparecerán en el menú
$texto_html = ”,
$anterior = true, //poner botón par anterior o texto
$siguiente = true, //poner botón para siguiente o texto
$final = false //poner la ultima pagina

){
#argumentos adicionales para cálculos
$texto_html = $texto_html==” ? array(‘[p]‘, ‘[p]‘) : $texto_html;
$total_paginas = ceil($total_objetos/$objetos_por_pagina); //total de paginas
$mitad_de_objetos_por_menu = round($objetos_por_menu/2); //mitad del menú
$mitad_de_objetos_por_menu_baj = floor($objetos_por_menu/2); //mitad del menú a la baja

#corrección de errores en pagina introducida
if(!is_numeric($pag_actual)){ $pag_actual = $_GET[$pag_actual] ? $_GET[$pag_actual] : $_POST[$pag_actual]; }
if($pag_actual<=0){ $pag_actual = 1; } elseif($pag_actual>$total_paginas){ $pag_actual = $total_paginas; }

if($pag_actual<=$mitad_de_objetos_por_menu){ //detectamos si esta al principio [desde el 1 hasta el $mitad_de_objetos_por_menu] $debug_zone = 'inicio'; $ini = 1; $fin = $objetos_por_menu<$total_paginas ? $objetos_por_menu : $total_paginas; } elseif($pag_actual<=($total_paginas-$mitad_de_objetos_por_menu)){ //detectamos si esta en la zona central [desde el $mitad_de_objetos_por_menu hasta el ($total_paginas-$mitad_de_objetos_por_menu)] $debug_zone = 'medio'; $ini = $mitad_de_objetos_por_menu_baj>$pag_actual ?
$mitad_de_objetos_por_menu_baj-$pag_actual : $pag_actual-$mitad_de_objetos_por_menu_baj;
$fin = $mitad_de_objetos_por_menu_baj+$pag_actual;
} else {
//detectamos si esta al final [desde ($total_paginas-$mitad_de_objetos_por_menu) hasta $total_paginas]
$debug_zone = ‘fin’;
$ini = $total_paginas-$objetos_por_menu+1;
$fin = $total_paginas;
$final = false;
}

//generamos el array de números necesarios para el menú
for($i=$ini;$i<=$fin;$i++){ $out['menu']['pags'][] = $i; $out['menu']['link'][] = '‘.$i.’‘;
if(is_array($texto_html)){
$out[‘menu’][‘html’][] = str_replace(‘[p]’, $i, ($pag_actual==$i ? $texto_html[1] : $texto_html[0]) );
} else {
$out[‘menu’][‘html’][] = str_replace(‘[p]’, $i, $texto_html);
}
}

#determinamos si se puede poner anterior
if($pag_actual!=1 && $anterior){
if($anterior===true){ $anterior = $pag_actual-1; }
$out[‘anterior’] = $pag_actual-1;
$out[‘menu’][‘pags’] = array_merge(array(‘anterior’ => $pag_actual-1 ), $out[‘menu’][‘pags’]);
$out[‘menu’][‘link’] = array_merge(array(‘anterior’ => ‘anterior‘ ), $out[‘menu’][‘link’]); if($siguiente!==true){
$out[‘menu’][‘html’] = array_merge(array(‘anterior’ => str_replace(‘[p]’, $pag_actual-1, $anterior) ), $out[‘menu’][‘html’]);
} elseif($siguiente!==true){
$out[‘menu’][‘html’] = array_merge(array(‘anterior’ => ‘anterior‘ ), $out[‘menu’][‘html’]);
}
} else { unset($anterior); }

#determinamos si se debe poner el max final
if($final){
$out[‘final’] = $total_paginas;
$out[‘menu’][‘pags’][‘final’] = $total_paginas;
$out[‘menu’][‘link’][‘final’] = ‘…’.$total_paginas.’‘;
if($final!==true){
$out[‘menu’][‘html’][‘final’] = str_replace(‘[p]’, $total_paginas, $final);
} elseif($final===true){
$out[‘menu’][‘html’][‘final’] = ‘…’.$total_paginas.’‘;
}
} else { unset($final); }

#determinamos si se puede poner siguiente
if($pag_actual!=$total_paginas && $siguiente){
$out[‘siguiente’] = $pag_actual+1;
$out[‘menu’][‘pags’][‘siguiente’] = $pag_actual+1;
$out[‘menu’][‘link’][‘siguiente’] = ‘siguiente‘;
if($siguiente!==true){
$out[‘menu’][‘html’][‘siguiente’] = str_replace(‘[p]’, ($pag_actual+1), $siguiente);
} elseif($siguiente===true){
$out[‘menu’][‘html’][‘siguiente’] = ‘siguiente‘;
}
} else { unset($siguiente); }

$out[‘ini’] = ($pag_actual*$objetos_por_pagina)-$objetos_por_pagina; //primer objeto de la página
$out[‘fin’] = ($pag_actual*$objetos_por_pagina)-1; //ultimo objeto de la página
return $out;
}
[/PHP]

La función comienza con el supuesto de que la 1º pagina es la pagina 1 (y no la cero) y el primer objeto es el 0 (no el uno) para seguir una correlación lógica entre la parte del código/consulta y la parte de la interfaz del usuario.
Si se encuentra con que la pagina es 0, o menor a 0 la sustituirá por 1 y si se encuentra que la pagina es mayor del numero total de paginas calculadas la sustituirá por la ultima pagina.

Como salida esta función da un array multidimensional que muestra las key ini que corresponde al número del primer objeto de la página, fin que corresponde al número del ultimo objeto de la pagina, y menu que contendrá a su vez en forma de array las tres formas de representación del menú pags (contiene un array con todos los números de pagina resultantes), link (que muestra un menú estándar echo de enlaces) y html (que muestra el menú personalizado a partir de los textos html).
Como opcional en cada punto y según las opciones seleccionadas, pueden aparecer adicionalmente en el array las key anterior, siguiente y final, que contendrían los botones específicos para ir a esas paginas.

Y ahora q sabemos como controlarlo todo y que sale en consecuencia vamos a hacer alguna prueba..

El primer ejemplo es el modo más simple y estático de usar la función. Usaremos los valores por defecto desactivando todos los botones adicionales para que solo aparezca el menú con enlaces estándar.
[PHP]
$menu = pag(
1, //pagina actual
600, //total de objetos a contar
6, //total de objetos a mostrar por cada pagina
10, //numeros que apareceran en el menu
”, //texto personalizado a obtener
false, //poner boton par anterior o texto
false, //poner boton para siguiente o texto
false //poner la ultimapagina
);
echo implode(‘ ‘, $menu[‘menu’][‘link’]).”
\n”;
echo ‘El primer objeto seria el objeto numero ‘.$menu[‘ini’].’, y el ultimo el ‘.$menu[‘fin’];
[/PHP]

El siguiente ejemplo muestra como hacer un menu que usa p como variable GET que determina en que pagina estamos, complementando el código automático. A demás incluye los botones siguiente y anterior. ha sido personalizado para que tenga 50 objetos y muestre 5 en cada pagina, teniendo un menu de 3 numeros
[PHP]
$menu = pag(
‘p’, //pagina actual
50, //total de objetos a contar
5, //total de objetos a mostrar por cada pagina
3, //numeros que apareceran en el menu
”, //texto personalizado a obtener
true, //poner boton par anterior o texto
true, //poner boton para siguiente o texto
false //poner la ultimapagina
);
echo implode(‘ | ‘, $menu[‘menu’][‘link’]).”
\n”;
echo ‘El primer objeto seria el objeto numero ‘.$menu[‘ini’].’, y el ultimo el ‘.$menu[‘fin’];
[/PHP]

El siguiente ejemplo tiene los botones persolanizado para que use la variable GET pagina para determinar en que pagina estamos a la vez que incluye el código HTML de cada botón.
[PHP]
$menu = pag(
‘pagina’, //pagina actual
60, //total de objetos a contar
5, //total de objetos a mostrar por cada pagina
4, //numeros que apareceran en el menu
[p]‘, //texto personalizado a obtener
‘, //poner boton par anterior o texto
‘, //poner boton para siguiente o texto
false //poner la ultimapagina
);
echo implode(‘ | ‘, $menu[‘menu’][‘link’]).”
\n”;
echo ‘El primer objeto seria el objeto numero ‘.$menu[‘ini’].’, y el ultimo el ‘.$menu[‘fin’];
[/PHP]

Como ultimo ejemplo vamos a hacer que muestra la misma estructura del anterior pero a demás, discrimina la pagina actual en el menu, y no le pone enlace para que se pueda diferenciar..
[PHP]
$menu = pag(
‘pagina’, //pagina actual
60, //total de objetos a contar
5, //total de objetos a mostrar por cada pagina
4, //numeros que apareceran en el menu
array( //texto personalizado indicando cuando es la pagina actual
[p]‘,
[p]
),
‘, //poner boton par anterior o texto
‘, //poner boton para siguiente o texto
false //poner la ultimapagina
);
echo implode(‘ | ‘, $menu[‘menu’][‘link’]).”
\n”;
echo ‘El primer objeto seria el objeto numero ‘.$menu[‘ini’].’, y el ultimo el ‘.$menu[‘fin’];
[/PHP]

Que lo disfrutéis..

2 opiniones en “pag(), paginación de resultados, objetos o paginas en PHP”

  1. Esta muy completa la función.

    Seria excelente un ejemplo con ajax, veré si lo hago con esta función y se los envio para que lo publiquen. GRacias

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *