Clase para paginar un array en php

Clase para paginar un array en php

He creado la siguiente clase (CPaginas) ya que no he encontrado una equivalente y generica para mostrar por paginas el contenido de cualquier array. La clase CPaginas sirve para paginar cualquier array. El pseudo algoritmo seria el siguiente:

  • Obtener array indexado en enteros
  • Construir un objeto pagina con el array obtenido
  • Recuperar el array reducido
El array a paginar debe estar indexado con las "keys" de primer nivel en enteros. Es decir: $arItems[0]=array(...); $arItems[1]=array(...); $arItems[.]=array(...); $arItems[i]=array(...); $arItems[.]=array(...); $arItems[n]=array(...);

La forma de usar la clase CPaginas

//Cualquier modelo $oModelo = new MModelo(); //Obtenemos un listado desde el modelo $arTabla = $oModelo->get_tabla(); //Pagina pedida $arUriParams[3]=$_GET['page']; $iPagina = $arUriParams[3]; //El listado es un array indexado por enteros //$sUrl = 'www.midomino.com/coches/?page=' el link con el que se generaran los botones de navegacion $oPagina = new CPaginas($arTabla, $iPagina, $sUrl, 8); //Reutilizamos el array dejando solo los items que le corresponde //a la pagina $iPagina $arTabla = $oPagina->get_items_to_show(); $sBotones = $oPagina->get_botones_in_html(); //Ahora solo queda recorrer $arTabla e ir imprimiendo su //contenido en pantalla y hacer un echo $sBotones;

El código de la clase CPaginas:

class CPaginas { private $_arItems; /** * Los items por pagina que se deberan mostrar * * @var mixed */ private $_iItemsPagina; private $_iPagina; private $_iNumPaginas; private $_isExacto = true; private $_sUrl; //$arItems: El array que se troceara en paginas //$iPagina: La pagina a mostrar //$sUrl: Es la url con la que se crearan los botones ejemplo: www.midominio.com/coches/electricos?page= //$iItemsPagina: La cantidad de items por pagina a mostrar public function __construct($arItems, $iPagina=1, $sUrl="", $iItemsPagina=15) { $this->_arItems = $arItems; $this->_iItemsPagina = $iItemsPagina; $this->_iPagina = $this->avoid_not_number($iPagina); $this->_iNumPaginas = $this->num_paginas_resultantes(); $this->_sUrl = $sUrl; } private function avoid_not_number($string) { $iEntero = $string; if(!is_numeric($iEntero)) { $iEntero = 1; } return $iEntero; } private function get_array_items() { $arResultado = array(); $arItems = $this->_arItems; $iItemsPagina = $this->_iItemsPagina; $iPagina = $this->_iPagina; $iNumPaginas = $this->_iNumPaginas; //Si la pagina recibida esta en el rango if($iPagina > 0 &amp;&amp; $iPagina <= $iNumPaginas) { //iKeyInicio = 8 x (4-1) = 24 $iKeyInicio = $iItemsPagina * ($iPagina - 1); //iKeyFinal = 24 + (8 - 1) = 24 + 7 = 31 //En caso de resto == 0 y que la pagina actual no sea //la ultima se puede aplicar el key Final asi $iKeyFinal = $iKeyInicio + ($iItemsPagina - 1); //Si la pagina actual es la ultima if($iPagina == $iNumPaginas &amp;&amp; !$this->_isExacto) { //Las paginas que respetan los items/pagina $iPaginasCompletas = $iNumPaginas - 1; //El numero de items distribuidos en estas paginas $iItemsDistribuidos = $iPaginasCompletas * $iItemsPagina; $iItemsUltimaPagina = count($arItems) - $iItemsDistribuidos; $iKeyFinal = $iKeyInicio + ($iItemsUltimaPagina - 1); } $k = 0; for($i=$iKeyInicio; $i<=$iKeyFinal; $i++) { $arResultado[$k] = $arItems[$i]; $k++; } //bug($arResultado, 'get_array_items'); } else //La pagina pedida no esta en el rango { $arResultado = null; } return $arResultado; } private function num_paginas_resultantes() { $arItems = $this->_arItems; $iItemsPagina = $this->_iItemsPagina; $iTotalItems = count($arItems); $iNumPaginas = intval( $iTotalItems / $iItemsPagina); $iResto = $iTotalItems % $iItemsPagina; //Si el resto es mayor que cero es porque se necesita //una pagina mas if($iResto > 0) { //Con esto indico que la ultima pagina no tendra //un listado respetando "itemps/pagina" sino que sera menor $this->_isExacto = false; $iNumPaginas++; } // bug($iNumPaginas); return $iNumPaginas; } private function get_array_navegacion() { $arBotones = array(); $iNumPaginas = $this->_iNumPaginas; $iPaginaActual = $this->_iPagina; //Hay al menos una pagina if($iNumPaginas > 0) { switch($iPaginaActual) { //En caso que se pase una pagina 0 o negativa (Fuera de rango) case($iPaginaActual < 1): $arBotones = "Error: pagina fuera de rango"; break; //Si solo existe una unica pagina case ($iPaginaActual==1 &amp;&amp; $iNumPaginas==1): //No hay botones de ningun tipo $arBotones = null; break; //Si estamos en la primera y hay mas de una case ($iPaginaActual==1 &amp;&amp; $iNumPaginas>1): $arBotones['nav_numeros'] = $this->get_botones_numero(); $arBotones['nav_siguiente'] = $this->get_botones_siguiente(); break; //Si no es ni la primera ni la ultima case ($iPaginaActual>1 &amp;&amp; $iPaginaActual<$iNumPaginas): $arBotones['nav_anterior'] = $this->get_botones_anterior(); $arBotones['nav_numeros'] = $this->get_botones_numero(); $arBotones['nav_siguiente'] = $this->get_botones_siguiente(); break; //Si es la ultima case ($iPaginaActual>1 &amp;&amp; $iPaginaActual==$iNumPaginas): $arBotones['nav_anterior'] = $this->get_botones_anterior(); $arBotones['nav_numeros'] = $this->get_botones_numero(); break; //Si es mayor a la ultima (fuera de rango) case ($iPaginaActual>$iNumPaginas): $arBotones = "Error: pagina fuera de rango pagina actual:$iPaginaActual, total paginas:$iNumPaginas"; default: } } return $arBotones; } private function get_botones_numero() { $arBoton = array(); $iPaginaNoBoton = $this->_iPagina; $iNumPaginas = $this->_iNumPaginas; $sUrl = $this->_sUrl; for($i=1; $i<=$iNumPaginas; $i++) { if($i != $iPaginaNoBoton) { //bug($sUrl,'url en get_botones numero'); $sTmpUrl = $sUrl . $i ."/"; ; $sBotonAnchor = "<span> <a href="\&quot;$sTmpUrl\&quot;">$i</a> </span>"; } else { $sBotonAnchor = "<span class="\&quot;stlPaginaActual\&quot;">$iPaginaNoBoton</span>"; } $arBoton[$i] = $sBotonAnchor; } return $arBoton; } private function get_botones_anterior() { $arBoton = array('inicio'=>"",'final'=>""); $iPaginaActual = $this->_iPagina; $iNumPaginas = $this->_iNumPaginas; $sUrl = $this->_sUrl; //Pagina 1 $sTmpUrl = $sUrl . 1 . "/"; $arBoton['inicio'] = "<span> <a href="\&quot;$sTmpUrl\&quot;">|<</a> </span>"; //Pagina anterior a la actual si la actual es > 1 $sTmpUrl = $sUrl . ($iPaginaActual-1). "/"; $arBoton['anterior'] = "<span> <a href="\&quot;$sTmpUrl\&quot;"><<</a> </span>"; return $arBoton; } private function get_botones_siguiente() { $arBoton = array('siguiente'=>"",'final'=>""); $iPaginaActual = $this->_iPagina; $iUltimaPagina = $this->_iNumPaginas; $sUrl = $this->_sUrl; //Solo hay siguiente si la pagina_actual es menor a la ultima pagina (o total de paginas) if($iPaginaActual<$iUltimaPagina) { $sTmpUrl = $sUrl . ($iPaginaActual+1). "/"; $arBoton['siguiente'] = "<span> <a href="\&quot;$sTmpUrl\&quot;">>></a> </span>"; } $sTmpUrl = $sUrl . $iUltimaPagina . "/"; $arBoton['final'] = "<span> <a href="\&quot;$sTmpUrl\&quot;">>|</a> </span>"; return $arBoton; } public function get_items_to_show() { return $this->get_array_items(); } public function get_botones_to_show() { return $this->get_array_navegacion(); } public function get_botones_in_html() { $sBotonesHtml = ""; $arBotones = $this->get_array_navegacion(); //bug($arBotones,'arbotones en get_botones_in_html'); //Navegacion inicio anterior if(!empty($arBotones['nav_anterior'])) { $sBotonesHtml .= $arBotones['nav_anterior']['inicio']; $sBotonesHtml .= $arBotones['nav_anterior']['anterior']; } //Navegacion numeros paginas if(!empty($arBotones['nav_numeros'])) { foreach($arBotones['nav_numeros'] as $sBoton) { $sBotonesHtml .= $sBoton; } } //Navegacion siguiente final if(!empty($arBotones['nav_siguiente'])) { $sBotonesHtml.= $arBotones['nav_siguiente']['siguiente']; $sBotonesHtml.= $arBotones['nav_siguiente']['final']; } return $sBotonesHtml; } }

Autor: Eduardo A. F.
Publicado: 17-04-2011 19:27
Actualizado: 02-07-2011 15:47