Paginación con CodeIgniter

Como ya he comentado en otros artículos y para aquellos que no lo conozcan, CodeIgniter es un framework para desarrollo en PHP que se basa en el patrón de diseño MVC. Trae muchas herramientas muy útiles y de uso común para los desarrolladores, incluyendo por supuesto una clase para facilitar la tarea de paginación.

Cuando hablo de paginación, me refiero a dividir resultados de consultas a bases de datos en más de una página, poniendo al pie de cada una de ellas, una serie de enlaces para que los usuarios las puedan navegar.

Cómo funciona la paginación

La paginación se utiliza cuando se tiene un resultado extenso producto de una consulta de una base de datos. Si el resultado fuera pequeño, bien podría entrar en una única página y no haría falta dividir los registros.

El funcionamiento básico se podría resumir de la siguiente manera. Cada vez que se carga la página, se realiza una consulta a la base de datos con parámetros para acotarla. Por ejemplo, si se pide la primera página, suponiendo que cada una muestra 20 resultados, se realizará una consulta a la base de datos que devolverá del primer al vigésimo resultado. Luego, la página 2, mostrará del vigésimo primero al cuadragésimo, y así sucesivamente.

En CodeIgniter, el código puede separarse de manera adecuada entre modelo, vista y controlador. El modelo realizará la consulta a la base de datos y devolverá los resultados, el controlador manejará la clase de paginación que facilitará todo el trabajo y la vista se encargará tanto de presentar los resultados como de mostrar los enlaces a cada una de las páginas.

Controlador: Manejo de la librería de paginación

Veamos el código del controlador. Tenemos una aplicación ficticia que tiene una tabla con frases célebres que queremos mostrar por pantalla.

La primera línea de código sirve para cargar la librería de paginación que será la que se encargará de resolver todo este asunto. En este ejemplo está hecho en el mismo método index del controlador, pero según el programa podría llegar a ser necesario cargarla directamente en el constructor. El array $opciones reunirá todos los parámetros necesarios para pasarle a la librería. Vamos a ver para qué sirve cada uno.

  • per_page: indica la cantidad de resultados que se quieren ver por página.
  • base_url: es la URL que se quiere paginar. En este caso, es el método index del controlador frase.
  • total_rows: es la cantidad total de resultados de la consulta. Se necesitará un método en el modelo que obtenga este valor.
  • uri_segment: este parámetro indica en qué segmento de la URI estará el parámetro de paginación. Los segmentos en CodeIgniter quedan delimitados por las barras. Por ejemplo en index.php/frase/index, el primer segmento es frase y el segundo es index. De esta forma, si se le indica el número 3, la librería utilizará el tercer segmento para enviar y recibir el parámetro que indica desde qué registro comienza la consulta. El resultado podrán verlo al ir navegando las páginas y tendrá una forma similiar a la siguiente: index.php/frase/index/30

Con todas esas opciones preparadas, se puede inicializar la paginación. Para ello, se utiliza el método initialize de la librería, al que se le pasa el array $opciones.

Luego hay que hacer la consulta a la base de datos, pero de eso se encarga el modelo. Es por eso que hacemos una llamada al método que corresponde para traer los datos. Como ya vimos, $opciones[‘per_page’] indica la cantidad de elementos que se quieren obtener por consulta y $desde, a partir de cuál. Esto se entenderá mejor en el modelo.

El valor de $desde se obtiene del tercer segmento de URI, siempre que esté definido. Si no lo está, entonces el valor que toma es 0. Esto significa que si no hay ningún valor en el tercer segmento, los resultados que se mostrarán comenzarán por la primera fila y se extenderá hasta la cantidad que se indique en $opciones[‘per_page’].

En $data[‘paginacion’] se obtiene el código HTML necesario para mostrar los enlaces a las páginas al pie de cada una de ellas. Esto bastante sencillo gracias al método create_links de la librería de paginación de CodeIgniter.

Finalmente, se carga la vista que corresponde.

Modelo: Consultas a la base de datos

Hemos visto que en el controlador hay dos llamadas al modelo. Una es para contar la cantidad total de elementos de la consulta, y la otra para devolver los resultados de la tabla que corresponde, acotados por los dos parámetros que mencionamos.

Veamos el primer método

Estoy usando la librería de manejo de bases de datos de CodeIgniter que, en este caso, estoy cargando en el constructor. El método getNumFrases cuenta todos los registros de la tabla $this->tb_frases, cuyo valor está definido como atributo privado al comienzo. Tengan en cuenta que omití la declaración de clase del modelo.

El otro método, es el que realiza las consultas acotando los resultados.

Se reciben dos parámetros. $limit se corresponde con $opciones[‘per_page’] y $start con $desde. Se realiza una consulta con limit, en este caso utilizando el método vinculado de la librería de base de datos. Luego, se obtienen los datos en $resultado, mediante el método get de la misma librería. Por último, se devuelve $resultado->result() que es el resultado de la consulta como un arreglo de objetos.

Vista: presentación de los datos

Falta mostrar los resultados por pantalla y los enlaces de paginación al pie de la página.

La información estaba en $data[‘lista’] así que en la vista se puede manejar como la variable $lista. A través de un foreach se puede iterar e ir obteniendo cada uno de los datos, que en este caso, se presentan en forma de tabla.

Al pie de la tabla, está la paginación. Simplemente hay que imprimir el valor de la variable $paginacion y los enlaces para navegar por las páginas aparecerán solos.

Más opciones de la clase de paginación

Hasta aquí hemos visto el funcionamiento básico de esta librería. Pero tiene aún más opciones para personalizarla. Si seguimos con el array $opciones para definir los parámetros, podríamos tener también:

  • $opciones[‘num_links’]: Es el número de enlaces que aparecerán antes y después de la página actual en los enlaces de paginación.
  • $opciones[‘use_page_numbers’]: ¿Notaron que el valor que se pasa en el tercer segmento es el que indica a partir de qué fila se va a seleccionar? ¿No pensaron intuitivamente que debía ser el número de página? Bueno, justamente si se pone esta variable en TRUE, el parámetro que se usará será el número de página.
  • $opciones[‘page_query_string’]: Si no les gusta usar segmentos, pueden hacer que el parámetro pase por get poniendo en TRUE este parámetro.
  • $opciones[‘query_string_segment’]: Es el nombre de la variable get que llevará el valor de la página, si ponen en TRUE el parámetro anterior.
  • $config[‘full_tag_open’]$config[‘full_tag_close’]: sirven para envolver con código HTML los enlaces de paginación con el objetivo de darle formato.
  • $config[‘display_pages’]: Poniendo esta variable en FALSE, no se mostrarán los números de página. Simplemente el enlace

Hay algunos parámetros para darle formato al primer enlace de las páginas, que por defecto está en inglés y dice “First”.

  • $config[‘first_link’] = ‘Primera’: Con ‘first_link’ se le puede cambiar la etiqueta o el nombre del enlace, como por ejemplo, cambiar el “First” por “Primera”.
  • $config[‘first_tag_open’]$config[‘first_tag_close’]: Envuelven al primer enlace con el objetivo de darle formato.

De la misma forma, hay opciones para personalizar el último enlace, el enlace siguiente y el anterior.

Conclusiones

La paginación de resultados de consultas de bases de datos es una de las funciones más utilizadas en el desarrollo web. La librería de paginación de CodeIgniter hace que realizar esta tarea sea muy fácil y se pueda lograr en apenas unos minutos. Siempre es conveniente entender un poco lo que hace para poder sacarle el máximo provecho.

Si les interesó lo relacionado a utilizar GET en lugar de segmentos, en un próximo artículo lo explicaré incluyendo código.

Soy programador web y me desempeño como Líder Técnico en Polar Bear Development. Trabajo con tecnologías como PHP, Javascript, MySQL y HTML5 para el desarrollo de sitios y sistemas web. Me especializo en Zend Framework 2 y otros frameworks MVC, como también en WordPress y otros CMS. Lidero equipos de desarrolladores trabajando con Scrum. Vivo en Buenos Aires, Argentina.
 

17 thoughts on “Paginación con CodeIgniter

  1. Un pequeño detalle: No dices cómo se llama el modelo. Mirando el controlador supongo que se llama “Frase_model”.

    Saludos.

  2. Estoy tratando de hacer una paginación con varibales mas variables de tipo get, como ordenar por precio etc, la cosa es que no me funciona y no he podido hacer nadaaaaaaa!

  3. La clase de paginación de CodeIgniter utiliza los URI segment para pasar las variables, en lugar de GET. Pero la paginación también está relacionada con las consultas a la base de datos ya que se necesita conocer la cantidad de filas resultantes y sus respectivos valores. En tu caso, entiendo el objetivo que buscás, pero no conozco el problema a fondo como para poder ayudarte.

    Saludos

  4. Ya encontre donde esta el error, cuando imprimo la consulta SQL el limit solo entrega un parametro, no los dos que deberia ser, “”$this->uri->segment(3);”” Eso llega vacío, si imprimes esa variable en tu ejemplo que te muestra ?

  5. Hola amigo podras ayudarme tengo un problema e cuanto a insert, bueno en el aspecto de enviar todos mis parametros desde un formulario logro hacer un insert, mi problema es: no lograr hacer un insert cuando necesito enviar datos de mi formulario y datos consultados desde mi base de datos.

    en mi controller tengo:
    /////////////////////////////////////////////////////////////////////////////
    //guardo en $periodo el resultado retornato en mi model
    $periodo=$this->inscripcion_model->get_periodo_actual();

    //$x y $y son los que traigo de mi formulario (mi vista) y $periodo es del llamado a la consulta anterior
    $insercion=$this->inscripcion_model->get_inscribir_alumno($x,$y,$periodo);

    ///////////////////////////////////////////////////////////////////////////////////////////
    model:
    public function get_inscribir_alumno($x, $y, $periodo)
    {
    $data = array(‘x’ =>$x ,’y’=>$y, ‘periodo_grupo’=>$periodo, );
    $this->db->insert(‘registrar’,$data);
    }
    ////////////////////////////////////////////////////////

    como veran no me permitira por la compatibilidad del tipo de datos agregar $periodo mi duda es como lograr hacer mi insert, alguna recomendacion o sugerencia se les agradece.

  6. Marco

    Me gustaría saber si la variable $periodo es algún tipo de fecha. Eso podría hacer que esté fallando la inserción. De todas formas sería más útil chequear qué valor está devolviendo al consulta y si es posible, pasar el framework a modo debug para ver los errores.

    Saludos!

  7. hola buenas, gracias por tu respuesta dejo la solución a mi problema por si algún principiante más como yo le llega a suceder
    public function nombre_funcion ()
    {
    $consulta = $this->db->query(“select id_p p from periodo where id_status=’2′”);
    $row=$consulta->row_array();
    return $row[‘periodo’];
    }

    gracias y saludos mi estimado

  8. has trabajado con postgres y haciendo usos de procedimientos almacenados??

    tengo esto en mi model:

    public function get_inscribir($nControl)
    {
    $consulta = $this->db->query(“CALL inscribir ($nControl)”);
    }

    mi configuracion de bd:

    $db[‘default’][‘hostname’] = ‘localhost’;
    $db[‘default’][‘username’] = ‘marco’;
    $db[‘default’][‘password’] = ‘password’;
    $db[‘default’][‘database’] = ‘database’;
    $db[‘default’][‘dbdriver’] = ‘postgre’;
    $db[‘default’][‘dbprefix’] = ”;
    $db[‘default’][‘pconnect’] = TRUE;
    $db[‘default’][‘db_debug’] = TRUE;
    $db[‘default’][‘cache_on’] = FALSE;
    $db[‘default’][‘cachedir’] = ”;
    $db[‘default’][‘char_set’] = ‘utf8’;
    $db[‘default’][‘dbcollat’] = ‘utf8_general_ci’;
    $db[‘default’][‘swap_pre’] = ”;
    $db[‘default’][‘autoinit’] = TRUE;
    $db[‘default’][‘stricton’] = FALSE;
    $db[‘default’][‘port’] = 5433;

    en lo que he leido que en mysql el driver deveria de ser mysqli

    y en postgres?? tienes alguna respuesta??

Comments are closed.