Créer un système de pagination automatique en PHP (exemple sur un livre d'or !)

Vous avez un livre d'or (ou autre) en PHP. Vous voulez afficher tous les messages mais il y en a trop pour tous les afficher sur une page ?
Alors ce tutoriel vous intéressera : je vais programmer avec vous un système de pagination automatique.
Ainsi, vous pourrez étaler vos messages sur plusieurs pages et le tout automatiquement !

2 commentaires Donner une note à l'article (5)

Article lu   fois.

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

1. Preface

Bonjour à tous !
Dans ce tutoriel, je vais tenter de vous expliquer un petit algorithme très courant mais pas si évident au début : la pagination automatique.
Je prendrai l'affichage des messages d'un livre d'or pour exemple.
Bien entendu, je ne vais pas vous déballer le code comme ça.
Nous allons le programmer ensemble.

2. Le but !

Notre but est de créer un système de pagination pour afficher les messages de notre livre d'or.
Jusqu'à maintenant, nous affichions tous les messages sur une seule page.
Vue la quantité actuelle, cela devient impossible.
Puisque de nouveaux messages sont régulièrement ajoutés au livre d'or, le système doit être automatisé.
Notre système devra en plus nous permettre de changer facilement le nombre de messages affichés par page.

3. La table utilisée pour le script

Pour notre script, nous allons utiliser la table d'un livre d'or tout simple :

id pseudo message

L'id est un champ qui ne comporte qu'un numéro. Ce numéro augmente de 1 à chaque nouveau message (auto incrémentation).
L'id va nous permettre de trier les messages : celui qui a le plus grand ID est celui qui a été posté le plus récemment.

Je vous conseille de copier le code SQL ci-dessous puis de l'installer chez vous afin de pouvoir tester le code.
J'ai même inséré quelques messages histoire d'avoir un peu de matière pour utiliser le script.

Table livredor pour pouvoir suivre ce tutoriel
Sélectionnez

CREATE TABLE `livredor` (
  `id` bigint(20) NOT NULL auto_increment,
  `pseudo` text,
  `message` text,
  KEY `id` (`id`)
) TYPE=MyISAM;
 
INSERT INTO `livredor` VALUES ('1','Tonio','Salut !
C\'est vraiment un super site ! ! !');
INSERT INTO `livredor` VALUES ('2','Jacot','Bravo !
Je te félicite pour ton site...');
INSERT INTO `livredor` VALUES ('3','Paul','Merci pour ce site très instructif !
Bonne continuation. :o)');
INSERT INTO `livredor` VALUES ('4','AZERTY','Cool.
Super design !');
INSERT INTO `livredor` VALUES ('5','MagaMan','Bravo !
Super le livre d\'or...');
INSERT INTO `livredor` VALUES ('6','Giro','10/10 !
Encore merci !');
INSERT INTO `livredor` VALUES ('7','Sms','tro bi1 ton site!');
INSERT INTO `livredor` VALUES ('8','All','C\'est rigolo comme site. ^^');
INSERT INTO `livredor` VALUES ('9','Moi','Bien joué.
C\'est un site très réussit !');
INSERT INTO `livredor` VALUES ('10','Weby','J\'adore !
Allez voir mon site :
www.monsite.com');
INSERT INTO `livredor` VALUES ('11','Cool','Très bon design, très bon site. ');
INSERT INTO `livredor` VALUES ('12','LEGEANTDU75','C\'est un peu vide mais sympa quand même.
Bon courrage.');
INSERT INTO `livredor` VALUES ('13','Prune','Oh lalalala !
Le boooo site ! ;o)');

4. Réalisation du script

Nous allons maintenant commencer à faire notre script.

4.0. Compter le nombre de pages

Pour commencer ce script, nous allons compter le nombre de pages.
Pour compter le nombre de pages, nous allons commencer par compter tous les messages contenus dans le livre d'or.
Ensuite, nous allons mettre le nombre total de messages dans la variable $total.
Voici le code qui nous permettra de compter le nombre de messages :

Compter le nombre de messages
Sélectionnez

//Une connexion SQL doit être ouverte avant cette ligne...
$retour_total=mysql_query('SELECT COUNT(*) AS total FROM livredor'); //Nous récupérons le contenu de la requête dans $retour_total
$donnees_total=mysql_fetch_assoc($retour_total); //On range retour sous la forme d'un tableau.
$total=$donnees_total['total']; //On récupère le total pour le placer dans la variable $total.

Maintenant que nous avons le nombre total de messages, nous allons en déduire le nombre de pages grâce à une division et nous le mettrons dans la variable $messagesParPage.
Pour ce faire, nous allons diviser le nombre total par le nombre de messages à afficher par page.
Attention, le résultat de la division risque d'être un nombre à virgule. Si c'est le cas, nous devrons prendre le nombre entier (sans virgule) supérieur car imaginons que vous affichiez 5 messages par page et que vous ayez 17 messages; 17/5=3,4 et 3,4 page n'est pas un nombre correct de pages. Il va donc falloir créer la 4ème page qui contiendra 2 messages.
Pour avoir le nombre entier supérieur, nous devons utiliser la fonction ceil()Lien vers la documentation PHP au sujet de la fonction ceil(). Dans notre code, nous mettrons le nombre total de pages dans la variable $nombreDePages. Voici donc le code précédent complété de manière à avoir le nombre de pages :

Calculer le nombre de pages
Sélectionnez

$messagesParPage=5; //Nous allons afficher 5 messages par page.
 
//Une connexion SQL doit être ouverte avant cette ligne...
$retour_total=mysql_query('SELECT COUNT(*) AS total FROM livredor'); //Nous récupérons le contenu de la requête dans $retour_total
$donnees_total=mysql_fetch_assoc($retour_total); //On range retour sous la forme d'un tableau.
$total=$donnees_total['total']; //On récupère le total pour le placer dans la variable $total.
 
//Nous allons maintenant compter le nombre de pages.
$nombreDePages=ceil($total/$messagesParPage);

4.1. Afficher les messages correspondants à la page actuelle

Maintenant que nous avons réussi à compter le nombre de pages, nous allons essayer d'afficher les messages de la page actuelle.
Pour cela, nous allons donc devoir sélectionner une gamme de messages dans la table livredor par ordre d'id décroissant (nous affichons les messages du plus récent au plus ancien).
Pour trier par ordre d'id décroissant, nous devons ajouter ceci à notre requête SQL (après les WHERE) : ORDER BY id DESC.

A savoir pour trier les résultats d'une requête SQL dans l'ordre croissant ou décroissant :
Vous devez écrire ORDER BY. Ensuite, vous ajoutez le nom du champ utilisé pour trier et pour terminer, vous pouvez ajouter DESC si vous souhaitez l'ordre décroissant. Si vous souhaitez l'ordre croissant, ne mettez rien...
Sachez que pour les nombres, il s'agit du classement ordinal que l'on a l'habitude d'utiliser et que pour les lettres, il s'agit de l'ordre alphabétique (croissant) ou inverse (décroissant).

Pour avoir une gamme précise (par exemple avoir depuis le message 5 jusqu'au message 10), nous devons ajouter ceci à notre requête SQL (après les WHERE et les ORDER BY) :

Préciser une gamme avec LIMIT
Sélectionnez

LIMIT 5, 5

À savoir pour obtenir un gamme précise :
Vous devez utiliser LIMIT. Ensuite, vous devez ajouter le numéro de la première entrée à afficher en sachant que le premier nombre n'est pas 1 mais 0, et pour terminer, le nombre total que l'on veut récupérer.
Exemple : pour afficher le message 6 au message 15, il faut mettre LIMIT 5, 10. Essayez de bien comprendre cela, c'est très important pour la suite.

Avant de faire notre requête, nous allons devoir savoir dans quelle page nous sommes.
Pour cela, nous allons dire que le numéro de la page actuelle est contenu dans la variable $_GET['page'] (donc sous la forme livredor.php?page=[n° de la page]).
Si la variable $_GET['page'] n'existe pas, nous allons dire que nous sommes dans la page 1.
Nous allons rajouter une petite condition de telle manière que si le numéro de page contenu dans $_GET['page'] est supérieur au nombre total de pages ($nombreDePage), alors la page sera la page maximum.
Pour savoir si une variable existe, il faut utiliser la fonction isset()Lien vers la documentation PHP au sujet de la fonction isset().
Voici donc le bout de code permettant d'afficher le numéro de la page ajouté au code précédent :

Savoir dans quelle page nous sommes
Sélectionnez

$messagesParPage=5; //Nous allons afficher 5 messages par page.
 
//Une connexion SQL doit être ouverte avant cette ligne...
$retour_total=mysql_query('SELECT COUNT(*) AS total FROM livredor'); //Nous récupérons le contenu de la requête dans $retour_total
$donnees_total=mysql_fetch_assoc($retour_total); //On range retour sous la forme d'un tableau.
$total=$donnees_total['total']; //On récupère le total pour le placer dans la variable $total.
 
//Nous allons maintenant compter le nombre de pages.
$nombreDePages=ceil($total/$messagesParPage);
 
if(isset($_GET['page'])) // Si la variable $_GET['page'] existe...
{
     $pageActuelle=intval($_GET['page']);
 
     if($pageActuelle>$nombreDePages) // Si la valeur de $pageActuelle (le numéro de la page) est plus grande que $nombreDePages...
     {
          $pageActuelle=$nombreDePages;
     }
}
else // Sinon
{
     $pageActuelle=1; // La page actuelle est la n°1    
}

Bon, maintenant que nous avons le n° de la page que nous souhaitons afficher, il faut qu'on fasse notre requête SQL et que l'on affiche les messages.
Notre requête va utiliser une ORDER BY pour avoir les messages dans l'ordre d'id décroissant de manière à avoir les messages les plus récents en premier.
Notre requête va aussi utiliser LIMIT pour sélectionner une plage de messages.
La partie que nous aurons à modifier à chaque page est la plage de messages.
Nous devons donc indiquer à LIMIT la première entrée à lire et combien d'entrées nous voulons lire ensuite.
Nous avons déjà la première partie, elle est contenue dans la variable $messagesParPage.
Il ne nous reste donc plus qu'à indiquer la première entrée à lire ($premiereEntree).
Nous allons devoir le calculer avec la page actuelle ($pageActuelle) et le nombre de messages par page ($messagesParPage).
Nous allons retirer 1 à $pageActuelle puis multiplier $pageActuelle par $messagesParPage.
Faites le calcul vous-même :
Pour $pageActuelle=1 : $pageActuelle-1=0, 0*5=0 => Nous lisons les entrées à partir de l'entrée 0 soit la première entrée.
Pour $pageActuelle=2 : $pageActuelle-1=1, 1*5=5 => Nous lisons les entrées à partir de l'entrée 5 soit la sixième (qui est la première de la deuxième page).
Si vous avez le courage, vous devriez pouvoir faire la requête vous même.
Voici donc le code précédent avec la requête en plus.
J'ai même rajouté l'affichage des messages en bonus (ce n'est pas l'objet du cours et si vous êtes ici, c'est que vous savez le faire...).

Afficher les messages de la page en cours
Sélectionnez

$messagesParPage=5; //Nous allons afficher 5 messages par page.
 
//Une connexion SQL doit être ouverte avant cette ligne...
$retour_total=mysql_query('SELECT COUNT(*) AS total FROM livredor'); //Nous récupérons le contenu de la requête dans $retour_total
$donnees_total=mysql_fetch_assoc($retour_total); //On range retour sous la forme d'un tableau.
$total=$donnees_total['total']; //On récupère le total pour le placer dans la variable $total.
 
//Nous allons maintenant compter le nombre de pages.
$nombreDePages=ceil($total/$messagesParPage);
 
if(isset($_GET['page'])) // Si la variable $_GET['page'] existe...
{
     $pageActuelle=intval($_GET['page']);
 
     if($pageActuelle>$nombreDePages) // Si la valeur de $pageActuelle (le numéro de la page) est plus grande que $nombreDePages...
     {
          $pageActuelle=$nombreDePages;
     }
}
else // Sinon
{
     $pageActuelle=1; // La page actuelle est la n°1    
}
 
$premiereEntree=($pageActuelle-1)*$messagesParPage; // On calcul la première entrée à lire
 
// La requête sql pour récupérer les messages de la page actuelle.
$retour_messages=mysql_query('SELECT * FROM livredor ORDER BY id DESC LIMIT '.$premiereEntree.', '.$messagesParPage.'');
 
while($donnees_messages=mysql_fetch_assoc($retour_messages)) // On lit les entrées une à une grâce à une boucle
{
     //Je vais afficher les messages dans des petits tableaux. C'est à vous d'adapter pour votre design...
     //De plus j'ajoute aussi un nl2br pour prendre en compte les sauts à la ligne dans le message.
     echo '<table width="400" border="0" align="center" cellpadding="0" cellspacing="0">
                <tr>
                     <td><strong>Ecrit par : '.$donnees_messages['pseudo'].'</strong></td>
                </tr>
                <tr>
                     <td>'.nl2br($donnees_messages['message']).'</td>
                </tr>
            </table><br /><br />';
    //J'ai rajouté des sauts à la ligne pour espacer les messages.   
}

Les messages sont affichés dirrectement à leur sortie de la base de données !
Cette méthode peut s'avérer dangereuse s'il s'agit de messages entrés par les visiteurs : l'un d'entre eux peut entrer du code HTML ou JavaScript et ainsi détourner vos visiteurs ou voler les cookies !
Il est donc fortement conseillé d'utiliser la fonction htmlentities()Lien vers la documentation PHP au sujet de la fonction htmlentities() qui va remplacer les caractères spéciaux ( < et > compris ) entités HTML et qui rendra donc les codes impossibles à interpréter par les navigateurs.

Voilà, la partie d'affichage des messages en fonction de la page actuelle est terminée mais il manque une chose très importante pour notre système de pagination automatique : la liste des pages.

4.2. Afficher la liste des pages

C'est la dernière chose qu'il nous reste à faire. Il s'agit d'un petit bout de code qui va nous permettre d'afficher la liste des pages avec un lien pointant vers chacune d'elles.
Il existe de très nombreuses manières d'afficher les pages qui sont plus ou moins compliquées.
La méthode que nous allons programmer ici est peut être la plus simple de toutes.
Cette méthode consiste tout simplement en une liste de toutes les pages. Cette méthode peut s'avérer inappropriée si vous avez des centaines de pages.
Je vous préviens, ce n'est pas compliqué à faire du tout.
D'ailleurs, c'est tellement simple que nous allons corser un peu la difficulté : nous allons encadrer la page actuelle par [ et ] et La page actuelle sera la seule qui ne sera pas un lien.
Rassurez vous, ça ne va pas être très compliqué... Nous allons devoir faire une boucle de type for.
Nous allons prendre pour départ la variable $i=1, nous allons l'incrémenter de 1 à chaque passage et nous allons nous allons continuer jusqu'à ce que $i>=$nombreDePages.
Dans cette boucle nous afficherons un chiffre ($i) qui sera un lien vers livredor.php?page=$i. Dans cette boucle, nous allons aussi mettre une condition de manière à ce que la page actuelle soit juste encadrée par [ et ].
Pour savoir s'il s'agit de la page actuelle, il suffira de savoir si $i==$pageActuelle. Si c'est le cas, on encadre ; sinon on en fait un lien. Voici donc le code précédent avec en plus la liste des pages.

Affichage la liste des pages
Sélectionnez

$messagesParPage=5; //Nous allons afficher 5 messages par page.
 
//Une connexion SQL doit être ouverte avant cette ligne...
$retour_total=mysql_query('SELECT COUNT(*) AS total FROM livredor'); //Nous récupérons le contenu de la requête dans $retour_total
$donnees_total=mysql_fetch_assoc($retour_total); //On range retour sous la forme d'un tableau.
$total=$donnees_total['total']; //On récupère le total pour le placer dans la variable $total.
 
//Nous allons maintenant compter le nombre de pages.
$nombreDePages=ceil($total/$messagesParPage);
 
if(isset($_GET['page'])) // Si la variable $_GET['page'] existe...
{
     $pageActuelle=intval($_GET['page']);
 
     if($pageActuelle>$nombreDePages) // Si la valeur de $pageActuelle (le numéro de la page) est plus grande que $nombreDePages...
     {
          $pageActuelle=$nombreDePages;
     }
}
else // Sinon
{
     $pageActuelle=1; // La page actuelle est la n°1    
}
 
$premiereEntree=($pageActuelle-1)*$messagesParPage; // On calcul la première entrée à lire
 
// La requête sql pour récupérer les messages de la page actuelle.
$retour_messages=mysql_query('SELECT * FROM livredor ORDER BY id DESC LIMIT '.$premiereEntree.', '.$messagesParPage.'');
 
while($donnees_messages=mysql_fetch_assoc($retour_messages)) // On lit les entrées une à une grâce à une boucle
{
     //Je vais afficher les messages dans des petits tableaux. C'est à vous d'adapter pour votre design...
     //De plus j'ajoute aussi un nl2br pour prendre en compte les sauts à la ligne dans le message.
     echo '<table width="400" border="0" align="center" cellpadding="0" cellspacing="0">
                <tr>
                     <td><strong>Ecrit par : '.stripslashes($donnees_messages['pseudo']).'</strong></td>
                </tr>
                <tr>
                     <td>'.nl2br(stripslashes($donnees_messages['message'])).'</td>
                </tr>
            </table><br /><br />';
    //J'ai rajouté des sauts à la ligne pour espacer les messages.   
}
 
echo '<p align="center">Page : '; //Pour l'affichage, on centre la liste des pages
for($i=1; $i<=$nombreDePages; $i++) //On fait notre boucle
{
     //On va faire notre condition
     if($i==$pageActuelle) //Si il s'agit de la page actuelle...
     {
         echo ' [ '.$i.' ] '; 
     }	
     else //Sinon...
     {
          echo ' <a href="livredor.php?page='.$i.'">'.$i.'</a> ';
     }
}
echo '</p>';

Voilà, le code de pagination automatique est terminé !

5. Pour aller plus loin

Il existe des librairies qui permettent de faire plus simplement et plus vite la même chose que le code que nous avons programmé.
C'est le cas de « Pager » qui est un package de la célèbre librairie Pear.
Pour l'utiliser, vous devez donc installer Pear et le package « Pager ».

Installer Pear : http://php.developpez.com/cours/installationpear/Tutoriel sur l'installation de Pear
Le site officiel de Pear : http://pear.php.netSite officiel de Pear
La page du package Pager : http://pear.php.net/package/PagerLa page du package Pager
Voici un exemple de code permettant de réaliser une pagination complète en peu de lignes !
Ce n'est qu'un morceau de code pour vous montrer que l'on n'est pas toujours obligés de réinventer la roue comme nous l'avons fait dans ce tutoriel...

Pagination avec Pear Pager
Sélectionnez

require_once ('Pager/Pager.php');
 
$nbItems=$this->DB->getNbItems ();
 
// construction d'un pager
$params = array(
    'mode'       => 'Sliding', // "Jumping" ou "Sliding" -fenêtre- Cela détermine le comportement de Pager.
    'perPage'    => 100, // Nombre d'éléments à afficher dans chaque page.
    'delta'      => 5, // Nombre de numéros de pages à afficher avant et après celui en cours.
    'totalItems' => $nbItems  // Tableau des éléments à répartir
);
$pager = & Pager::factory($params);
$links = $pager->getLinks();
 
// Récupération des données en prenant en compte l'id de la page courante et le nombre d'items par page
$members = $this->DB->getAllItems(100, $pager->getCurrentPageID());
 
echo $links['all'];

Ce code utilise ce que l'on appelle la POO (Programmation Orientée Objet). C'est à dire qu'elle utilise des classes et des objets.
La POO est une notion très importante en PHP et surtout depuis la sortie de PHP5.
Si vous êtes intéressé(e) par la POO et PHP5, je vous conseille ce livre qui m'a appris beaucoup de choses : PHP5 avancéLien vers la critique du livre PHP5 avancé

6. Conclusion

Ce tutoriel est maintenant terminé, j'espère que vous y avez appris des techniques et que vous avez compris.
Voici pour ceux qui voudraient tester le script à "copier - coller". Il faudra l'enregistrer sous le nom livredor.php et modifier les identifiants de connexion à la base de données. Bien entendu, il faudra que vous ayez aussi récupéré la table livredor que je vous ai fournie...

Code final
Sélectionnez

<html>
<head>
<title>Exemple de pagination automatique sur un livre d or</title>
</head>
<body>
<?php
//Connexion à la base de données
mysql_connect('serveur', 'utilisateur', 'motdepasse');
mysql_select_db('basededonnees');
 
$messagesParPage=5; //Nous allons afficher 5 messages par page.
 
//Une connexion SQL doit être ouverte avant cette ligne...
$retour_total=mysql_query('SELECT COUNT(*) AS total FROM livredor'); //Nous récupérons le contenu de la requête dans $retour_total
$donnees_total=mysql_fetch_assoc($retour_total); //On range retour sous la forme d'un tableau.
$total=$donnees_total['total']; //On récupère le total pour le placer dans la variable $total.
 
//Nous allons maintenant compter le nombre de pages.
$nombreDePages=ceil($total/$messagesParPage);
 
if(isset($_GET['page'])) // Si la variable $_GET['page'] existe...
{
     $pageActuelle=intval($_GET['page']);
 
     if($pageActuelle>$nombreDePages) // Si la valeur de $pageActuelle (le numéro de la page) est plus grande que $nombreDePages...
     {
          $pageActuelle=$nombreDePages;
     }
}
else // Sinon
{
     $pageActuelle=1; // La page actuelle est la n°1    
}
 
$premiereEntree=($pageActuelle-1)*$messagesParPage; // On calcul la première entrée à lire
 
// La requête sql pour récupérer les messages de la page actuelle.
$retour_messages=mysql_query('SELECT * FROM livredor ORDER BY id DESC LIMIT '.$premiereEntree.', '.$messagesParPage.'');
 
while($donnees_messages=mysql_fetch_assoc($retour_messages)) // On lit les entrées une à une grâce à une boucle
{
     //Je vais afficher les messages dans des petits tableaux. C'est à vous d'adapter pour votre design...
     //De plus j'ajoute aussi un nl2br pour prendre en compte les sauts à la ligne dans le message.
     echo '<table width="400" border="0" align="center" cellpadding="0" cellspacing="0">
                <tr>
                     <td><strong>Ecrit par : '.stripslashes($donnees_messages['pseudo']).'</strong></td>
                </tr>
                <tr>
                     <td>'.nl2br(stripslashes($donnees_messages['message'])).'</td>
                </tr>
            </table><br /><br />';
    //J'ai rajouté des sauts à la ligne pour espacer les messages.   
}
 
echo '<p align="center">Page : '; //Pour l'affichage, on centre la liste des pages
for($i=1; $i<=$nombreDePages; $i++) //On fait notre boucle
{
     //On va faire notre condition
     if($i==$pageActuelle) //Si il s'agit de la page actuelle...
     {
         echo ' [ '.$i.' ] '; 
     }	
     else //Sinon...
     {
          echo ' <a href="livredor.php?page='.$i.'">'.$i.'</a> ';
     }
}
echo '</p>';
?>
</body>
</html>

Je remercie hugo123Lien vers le profil de hugo123 pour m'avoir aidé à propos de Pear Pager !
Si vous avez un problème ou si vous voyez une erreur dans ce tutoriel, prévenez moi, c'est comme cela qu'on avance...
La FAQ au sujet des boucles en PHP :
FAQ : Boucles en PHPFAQ au sujet des boucles en PHP

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur ( http://www.lahacheweb.comLa Hache Web ).