Autor Tema: Paginación de Resultados con CakePHP & MySQL  (Leído 5958 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado mxgxw

  • Global Moderator
  • The Communiter-
  • *
  • Mensajes: 5665
  • Starlet - 999cc
    • mxgxw
Paginación de Resultados con CakePHP & MySQL
« : marzo 30, 2007, 08:01:54 pm »
Introducción

Cuando se trabaja con aplicaciones web y tablas, debemos siempre de mostrar el resultado de nuestras consultas a nuestros usuarios. Cuando estos datos se vuelven demasiados, presentarlos al usuario se vuelve complicado y nos agrega carga extra si siempre mostramos todos los datos.

La paginación nos permite mostrar los datos en grupos, con lo que obtenemos dos grandes beneficios, primero reducir el uso de recursos por parte de nuestra aplicación, y segundo podemos crear interfaces más amigables para el usuario.

Con este tutorial y usando CakePHP+MySQL podremos crear un control de paginación simple desde cero para una tabla de contactos.

Requisitos:

  • CakePHP
  • MySQL
  • CakePHP configurado y funcional

1-Los datos

Antes que nada, debemos de crear una tabla en nuestra base de datos. En MySQL podemos crear una tabla de contactos con el siguiente código:

CREATE TABLE contactos
  (
    id INT UNSIGNED AUTO_INCREMENT NOT NULL,
    nombres VARCHAR(150) NOT NULL,
    apellidos VARCHAR(150) NOT NULL,
    telefono INT(8) NOT NULL,
    PRIMARY_KEY(id)
  );

Lo que nos queda, es ingresar algunos datos:

INSERT INTO contactos(nombres,apellidos,telefono)
   VALUES('Mario','Gomez',22905930),
         ('Karla','Gonzalez',22475423),
         ('Ernesto','Rivera',22445787),
         ('Juan','Sanchez',22417251),
         ('Ricardo','Lemus',22453652),
         ('Flor','Aguilar',22451535),
         ('David','Ochoa',22454584),
         ('Catalina','Cruz',22334525),
         ('Marvin','Arriaza',22453541),
         ('Carlos','Batres',26532458),
         ('Juan','Alfaro',22453668),
         ('Marina','Salazar',22639586),
         ('Karla','Miranda',22365984),
         ('Salvador','Hernandez',22654854),
         ('Marta','Urrutia',22635428),
         ('Benjamin','Campos',22364586),
         ('Alejandro','Rodriguez',554822416);

Ahora que ya tenemos nuestra tabla con los datos, es cuando podemos ponernos a jugar un poquito con PHP.

2-El Modelo.

El primer paso es crear nuestro modelo de datos, para este ejemplo será bastante simple ya que tenemos una única tabla. Asumiendo que ya tenemos instalado y configurado nuestro Cake, creamos un archivo con nombre Contacto.php en el directorio <CAKE>/app/models/.

Código: (Contacto.php) [Seleccionar]
<?php
class Contacto extends AppModel {
  var 
$name "Contacto";
}
?>


Como hemos seguido la nomenclatura utilizada por Cake para el diseño de nuestra tabla, entonces no hay necesidad de hacer nada mas.

Nota: Si el nombre de la tabla en la base de datos no es el plural (en inglés), de el nombre de la clase, entonces debemos de definir el nombre de la tabla a utilizar con var $useTable = <nombretabla>;. En inglés, el plural de cualquier objeto se obtiene agregando una 's' al final del nombre del mismo. Por ejemplo para contact (Contacto en inglés), el plural corresponde a contacts. En español no sucede igual y podríamos tener problemas con algunas palabras. Por ejemplo para Perfil, el plural en español es Perfiles. En este caso y para un modelo con nombre Perfil deberíamos de utilizar var $useTable="perfiles";.


3-Entendiendo la paginación.

Antes de comenzar a editar código, vamos a entender un poquito como funciona esto de la paginación. Vamos a hacer un par de calculos y vamos a crear un algoritmo que nos sirva para cualquier base de datos.

Primero, antes que nada debemos de conocer cuantos resultados nos devuelve una consulta. Para hacerlo siempre existen funciones de conteo de resultados en los gestores. En mysql la siguiente consulta nos deberá de devolver la cantidad de filas para la tabla contactos:

SELECT COUNT(*) FROM contactos;

El resultado deberá de ser más o menos el siguiente:
Código: [Seleccionar]
+----------+
| COUNT(*) |
+----------+
|       17 |
+----------+
1 row in set (0.00 sec)

Es decir, que debemos de mostrarle 17 resultados al usuario. Sin embargo imaginemos que nos interesa mostrarle únicamente 4 por vez. Entonces tenemos que hacer un par de cálculos:

Total de resultados = 17
Resultados a mostrar = 4
Páginas totales = Total de resultados / Resultados a mostrar = 17/4 = 4.25

Aquí nos encontramos con un problema, necesitamos 4 y 1/4 de página para mostrar todos los resultados. Sin embargo no es posible mostrar únicamente media página, así que lo que hacemos es aproximar el número de páginas al entero positivo mayor. Es decir que necesitaremos 15 páginas para mostrar todos los resultados.

Tip: PHP cuenta con una función que nos facilita ese trabajo, y es la funcion "ceil(<numero>)", que aproxima todo numero decimal a su entero positivo mayor. Por ejemplo ceil(2.1) = 3, ceil(2.7) = 3.

4- Modificando nuestro modelo

Ahora que ya conocemos todos los datos necesarios para realizar una páginacion, vamos a modificar un poco nuestro modelo original para facilitarnos el trabajo. Para ello vamos a utilizar la función findCount(<condiciones>), que es el equivalente en SQL a "SELECT COUNT(*) FROM WHERE <condiciones>".

Vamos a crear una función "totalContactos()" que nos devuelva el total de contactos de la tabla.

Código: (contacto.php) [Seleccionar]
<?php
class Contacto extends AppModel {
  var 
$name "Contacto";

  
// Devuelve el total de contactos almacenados
  // en la tabla "contactos".
  
function totalContactos() {
    return 
$this->findCount();
  }
}
?>


5- Creando un Controlador adecuado

Ahora que ya conocemos como funciona la paginación y como obtener el total de resultados para una consulta, vamos a crear un controlador que establezca todas las variables necesarias para enviar a la vista.

En el controlador debemos de obtener todos los contactos que queremos mostrar y establecerlos como variable para pasarlos a la vista. También necesitamos pasar el total de páginas y la cantidad de perfiles que se muestran.

Creamos nuestro controlador como contactos_controller.php en el directorio <CAKE>/app/controllers
Código: (contactos_controller.php) [Seleccionar]
<?php
class ContactosController extends AppController {

  
// IMPORTANTE
  // Debes especificar que
  // utilizaras el modelo Contacto
  
var $models = array(
    
'Contacto'
  
);

  
// Utilizaremos el helper Html
  // para crear los links
  
var $helpers = array(
    
'Html'
  
);
  
  function 
listar($pagina=1) {
  
    
$mostrarResultados 4;

    
// Obtiene $mostrarResultados de la tabla contactos
    // de la pagina $pagina
    
$contactos $this->Contacto->findAll(nullnull, ,$mostrarResultados $pagina);

    
// Establecemos el arreglo que contiene
    // a los contactos
    
$this->set('contactos'$perfilmodelos);


    
// Obtenemos el numero total de contactos
    
$totalContactos $this->Contacto->totalContactos();

    
// Variables de la paginacion
    
$this->set("totalContactos"$totalContactos);
    
$this->set("mostrarResultados"$showResults);
    
$this->set("paginaActual"$pagina);
    
$this->set("totalPaginas"ceil($totalContactos $mostrarResultados));
  }
}
?>


La función que nos facilita el trabajo de paginación es "findAll(<condiciones>,<campos>,<columna_a_ordenar>,<limite>,<pagina>". Como estamos obteniendo todos los campos, dejamos los primeros tres parametros en null.


4-Creando la vista

Lo único que nos queda es crear una vista para mostrar nuestros datos. Como ya establecimos todas las variables que ibamos a necesitar esta resulta la parte más sencilla.

Vamos a crear el archivo listar.thtml en <CAKE>/app/views/contactos/

Código: (listar.thtml) [Seleccionar]
<html>
  <head><title>EJemplo de paginación</title></head>
  <body>
  <table>
    <tr>
      <td>Nombres</td>
      <td>Apellidos</td>
      <td>Telefono</td>
    </tr>
<?php
// Si no hay datos a mostrar
if(empty($contactos)) { ?>

    <tr>
      <td colspan="3">No hay datos que mostrar</td>
    </tr>
<?php
// Si hay datos:
} else {

// Mostramos cada uno de los datos
// encontrados
  
foreach($contactos as $i=>$contacto) {
?>

    <tr>
      <td><?php echo $contacto['Contacto']['nombres']; ?></td>
      <td><?php echo $contacto['Contacto']['apellidos']; ?></td>
      <td><?php echo $contacto['Contacto']['telefono']; ?></td>
    </tr>
   
<?php 
  
// Fin foreach
// Fin Hay datos ?>

<!--// POR ULTIMO CREAMOS LOS VINCULOS DE NAVEGACION //-->
<p align="center">
<?php
// Si no estamos en la primera p&#225;gina
// Y hay mas de dos p&#225;ginas
// mostramos el vinculo "Primera"
if(($paginaActual>1) && ($totalPaginas>2)) { ?>

  [<?php echo $html->link("Primera","/contactos/listar/1"); ?>]
<?php
}
?>

<?php
// Si no estamos en la primera p&#225;gina
// mostramos el vinculo "Anterior"
if($paginaActual>1) { ?>

  [<?php echo $html->link("Anterior","/contactos/listar/".($paginaActual-1)); ?>]
<?php
}
?>

<?php
// Si no estamos en la &#250;ltima p&#225;gina
// mostramos el vinculo "Siguiente"
if($paginaActual<$totalPaginas) { ?>

  [<?php echo $html->link("Siguiente","/contactos/listar/".($paginaActual+1)); ?>]
<?php
}
?>

<?php
// Si no estamos en la ultima pagina
// Y hay mas de dos p&#225;ginas
// mostramos el vinculo "Ultima"
if(($paginaActual<$totalPaginas) && ($totalPaginas>2)) { ?>

  [<?php echo $html->link("&#218;ltima","/contactos/listar/".$totalPaginas); ?>]
<?php
}
?>
<br />
<?php
// Si hay mas de una p&#225;gina entonces
// mostramos la p&#225;gina actual
if($totalPaginas>1)
?>

  Página <?php echo $paginaActual ?> de <?php echo $totalPaginas ?>;
<?php
}
?>

</p>
  </table>
  </body>
</html>
« Última Modificación: marzo 30, 2007, 08:10:44 pm por mxgxw »


Desconectado rdoggsv

  • Administrator
  • The Communiter-
  • *
  • Mensajes: 6530
  • "Once you go arch , u never go back"
    • SV CommunitY
Re: Paginación de Resultados con CakePHP & MySQL
« Respuesta #1 : marzo 31, 2007, 12:05:12 am »
Hey que bonito esta esto , yo ocupe el componente de un "andy dawson" , y en la rama de desarrollo de cakephp ya es parte integral tambien de cake lo de paginación, pero no hay nada mas bonito que tener lo propio hecho en lugar de usarl o de los demas  :sur:

Desconectado NoeL

  • Administrator
  • The Communiter-
  • *
  • Mensajes: 3257
    • SvCommunity
Re: Paginación de Resultados con CakePHP & MySQL
« Respuesta #2 : abril 30, 2007, 12:32:49 pm »
Bastante bonito pero en lo personal me quedo con el componente que ha mencionado rdoggsv  :roll:

Desconectado kerberoz

  • The Communiter-
  • *
  • Mensajes: 3713
Re: Paginación de Resultados con CakePHP & MySQL
« Respuesta #3 : abril 30, 2007, 12:42:55 pm »
Interesante, en el ejemplo usas una sola tabla se puede usar una consulta de varias tablas?

Donde consigo el CakePHP y ke mas se puede hacer con el me llego esa onda  :thumbsup:
El aguinaldo es un invento comunista; pero eso no te molesta, ¿Verdad?

Desconectado NoeL

  • Administrator
  • The Communiter-
  • *
  • Mensajes: 3257
    • SvCommunity
Re: Paginación de Resultados con CakePHP & MySQL
« Respuesta #4 : abril 30, 2007, 12:57:21 pm »
Interesante, en el ejemplo usas una sola tabla se puede usar una consulta de varias tablas?

Donde consigo el CakePHP y ke mas se puede hacer con el me llego esa onda  :thumbsup:

dependiendo de la Logica Relacional que tengas cakephp se encarga de resolver el asunto del amarrado de diferentes tablas

lo podes conseguir aqui:

http://cakephp.org/

100% Open Source