tuto

Système de pagination

Nous allons voir comment effectuer un système de pagination sur vos données (galerie d’images, articles, liste de commentaires, etc) à partir d’une base de données et d’une classe PHP.

 

Etape 1 : Création de la table

Bon pour ce tuto il nous faut de la matière, voici une table que vous pouvez reprendre, qui contient une vingtaine de lignes, assez pour travailler :)

--
-- Structure de la table `commentaires`
--

CREATE TABLE IF NOT EXISTS `commentaires` (
  `id` int(11) NOT NULL auto_increment,
  `nom` varchar(100) NOT NULL,
  `texte` mediumtext NOT NULL,
  PRIMARY KEY  (`id`)
) TYPE=MyISAM  AUTO_INCREMENT=20 ;

--
-- Contenu de la table `commentaires`
--

INSERT INTO `commentaires` (`id`, `nom`, `texte`) VALUES
(1, 'MonsieurCool', 'Ouaw c''est pas dur en fait Ajax'),
(2, 'Péssimiste', 'Un peu quand même si...'),
(3, 'Paco', 'Ouai mais nan...'),
(4, 'MrMystère', 'Eh dis donc tu as du t''embeter a taper ces commentaires pour ton tuto'),
(5, 'François', 'Oui j''avoue c''est pas la partie la plus palpitante, mais au moins vous pourrez prendre du plaisir a les supprimer.'),
(6, 'Léo ', 'PGM!!'),
(7, 'François', 'Quoiii?? -->Virez moi le commentaire au dessus tout de suite.\r\n'),
(8, 'Tartampion', 'Bon c''est bon t''as assez de lignes dans ta table la... on va pouvoir s''amuser!'),
(9, 'François', 'Ouai ok! J''espere que vous vous êtes pas fait chier a lire tout ca quand même!!'),
(10, 'MonsieurCool', 'Ouaw c''est pas dur en fait Ajax'),
(12, 'Péssimiste', 'Un peu quand même si...'),
(13, 'Paco', 'Ouai mais nan...'),
(14, 'MrMystère', 'Eh dis donc tu as du t''embeter a taper ces commentaires pour ton tuto'),
(15, 'François', 'Oui j''avoue c''est pas la partie la plus palpitante, mais au moins vous pourrez prendre du plaisir a les supprimer.'),
(16, 'Léo ', 'PGM!!'),
(17, 'François', 'Quoiii?? -->Virez moi le commentaire au dessus tout de suite.\r\n'),
(18, 'Tartampion', 'Bon c''est bon t''as assez de lignes dans ta table la... on va pouvoir s''amuser!'),
(19, 'François', 'Ouai ok! J''espere que vous vous êtes pas fait chier a lire tout ca quand même!!');

Etape 2 : Notre classe Pagination

Pour ce tuto, nous allons utiliser une classe Pagination, qui n’est rien d’autre que 2 méthodes statiques. (Le fonctionnement est donc similaire aux fonctions). Voici son code:

<?php
/**
 * Méthode qui gère la pagination
 * @author Snoupix.com tutoriaux, actualités et encylopédie sur la programmation et le design Web...
 * Ce code est sous licence Creative Commons: Enjoy!
 */
   class Pagination{
   		/**
   		 * Fonction qui retourne une div de pagination en fonction de plusieurs paramètres
   		 * @return $html une chaine contenant une div.
   		 * @param object $chemin
   		 * @param object $nomget
   		 * @param object $total
   		 * @param object $courante[optional]
   		 * @param object $affichage[optional]
   		 */
		public static function affiche($chemin,$nomget,$total,$courante=1,$affichage=2){
			//variable contenant le code HTML a retourner
			$html = '';
			//Si il n'y a pas plus d'une page on renvoit rien...
			if($total<=1)
				return $html;

			$precedent = $courante-1;
			$suivant = $courante+1;
			$textePrecedent = '« préc';
			$texteSuivant = 'suiv »';

			$html .= '<div class="pagination">';

			/*Boutons précédent*/
			if ($courante == 2) // si on est sur la page 2, Nous retournons sur la page initiale (permet d'éviter les doublons index.php et index.php?page=1)
            	$html.= Pagination::lien($chemin,$textePrecedent);
       		elseif($courante > 2) // si la page courante est supérieure à 2 le bouton précédent renvoit sur la page dont le numéro est immédiatement inférieur
            	$html.= Pagination::lien($chemin,$textePrecedent,$nomget,$precedent);
        	else // sinon on désactive le bouton précédent
            	$html.= '<span class="desactive">'.$textePrecedent.'</span>';

			/*Affichage des numéros des pages*/

			if($total < 7 + $affichage*2){
				//affiche tous les numéros
				$html.= ($courante == 1) ? '<span class="courante">1</span>' : Pagination::lien($chemin,'1',$nomget,1);

	            // On boucle toutes les pages restantes boucle for
	            for ($i = 2; $i <= $total; $i++){
	                if ($i == $courante) // La page courante est affichée différemment
	                    $html.= '<span class="courante">'.$i.'</span>';
	                else
	                    $html.= Pagination::lien($chemin,$i,$nomget,$i);
	            }
			} elseif($total > 5 + ($affichage * 2)){
				/*Il y'en a trop donc il va falloir des "..." */
				if($courante < 1+($affichage * 2)){
					$html.= ($courante == 1) ? '<span class="courante">1</span>' : Pagination::lien($chemin,'1',$nomget,1);

		             // On boucle toutes les pages restantes boucle for
		           for($i = 2; $i < 4 + ($affichage * 2); $i++){
		                if ($i == $courante)// La page courante est affichée différemment
		                    $html.= '<span class="courante">'.$i.'</span>';
		                else
		                    $html.= Pagination::lien($chemin,$i,$nomget,$i);
					}
					  // les ... pour marquer la troncature
                	$html.= " ... ";

	                // et enfin les deux dernières pages
	                $html.= Pagination::lien($chemin,$total-1,$nomget,$total-1);
	                $html.= Pagination::lien($chemin,$total,$nomget,$total);
				}elseif($total - ($affichage * 2) > $courante && $courante > ($affichage * 2)){
	                // on affiche les deux premières pages
	                $html.= Pagination::lien($chemin,'1',$nomget,1);
	                $html.= Pagination::lien($chemin,'2',$nomget,2);

	                // les ... pour marquer la troncature
	                $html.= " ... ";

	                // puis sept pages : les trois précédent la page courante, la page courante, puis les trois lui succédant
	                for ($i= $courante - $affichage; $i<= $courante + $affichage; $i++){
	                    if ($i== $courante)
	                        $html.= '<span class="courante">'.$i.'</span>';
	                    else
	                        $html.= Pagination::lien($chemin,$i,$nomget,$i);
	                }

	                // les ... pour marquer la troncature
	                $html.= " ... ";

                	// et enfin les deux dernière spages
                	$html.= Pagination::lien($chemin,$total-1,$nomget,$total-1);
                	$html.= Pagination::lien($chemin,$total,$nomget,$total);
            	}
				 else{
	                // on affiche les deux premières pages
	                $html.= Pagination::lien($chemin,'1',$nomget,1);
	                $html.= Pagination::lien($chemin,'2',$nomget,2);

	                // les ... pour marquer la troncature
	                $html.= " ... ";

	                // et enfin les neuf dernières pages
	                for ($i = $total - (2 + ($affichage * 2)); $i <= $total; $i++){
	                    if ($i == $courante)
	                        $html.= '<span class="courante">'.$i.'</span>';
	                    else
	                        $html.= Pagination::lien($chemin,$i,$nomget,$i);
	                }
 	           }
			}

			/*Bouton suivant*/
			if ($courante < $total)
            	$html.= Pagination::lien($chemin,$texteSuivant,$nomget,$suivant);
        	else
			    $html.= '<span class="desactive">'.$texteSuivant.'</span>';

			$html .= '</div>';

			echo $html;
   		}

		/**
		 * Méthode qui renvoit un lien en fonction de plusieurs paramètres
		 * @return $lien un lien
		 * @param object $chemin notre fichier
		 * @param object $texte texte du lien
		 * @param object $parametre[optional] parametre GET
		 * @param object $valeur[optional] valeur du parametre GET
		 */
		public static function lien($chemin,$texte,$parametre='',$valeur=''){
			$lien = '<a href="'.$chemin;

			if(!empty($parametre))
				$lien .= '?'.$parametre.'='.$valeur;

			$lien .= '">'.$texte.'</a>';
			return $lien;
		}
   }
?>

Ne vous embettez pas à rentrer dans les détails de ce code, sachez juste qu’elle renvoie une div html, contenant la pagination à afficher. Pour la faire fonctionner, nous avons besoin de 5 paramètres:

  • $chemin qui est le nom de votre url (par exemple « maPage.php »)
  • $nomGet qui sera le nom de votre variable passée en paramètre dans votre url (ex: index.php?numeroPage=2 renverra la 2ème page)
  • $total qui est le nombre total de pages
  • $courante qui est le numéro de la page sur laquelle on se trouve
  • $affichage qui équivaut au nombre d’éléments minimum à afficher de chaque côté de la page courante (ex: si on est à 3, cela donnera ceci: …5 6 7 8 9 10 11…)

Etape 3 : Notre fichier à paginer

Vous l’aurez compris, il va falloir dans notre fichier PHP ou l’on veut afficher nos éléments connaître certaines valeurs énoncés précédemment comme le nombre total de pages. Voici la démarche à effectuer:

  1. Dans un premier temps nous allons compter le nombre d’éléments dans notre table (on utilisera pour ceci le mot clé COUNT(*) en SQL.
  2. Ensuite nous allons déduire le nombre total de pages en divisant le nombre d’items par le nombre d’items par page (j’ai choisi d’en afficher 2 par pages).
  3. Nous allons par la suite, identifier une variable qui correspondra au numéro de la page courante vu par l’utilisateur (il correspondra à $_GET['idPage'] et si ce dernier est nul, nous le mettrons par défault à 1)
  4. Nous exécuterons la requête qui permettra d’afficher les élements voulus en utilisant la clause LIMIT de SQL. La première valeur de LIMIT correspond à la pageCourante*le nombre d’items par page – le nombre d’items par page. La deuxième valeur correspond au nombre d’élements à afficher (ici cela correspond au nombre d’items par page).
  5. Pour finir nous afficherons le résultat de notre requête et éxécuterons notre fonction de pagination (tout en ayant au préalable inclus notre classe Pagination)

Voici le contenu de notre fichier que j’ai apellé très instinctivement: « index.php »:

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr" dir="ltr"&gt;
	&lt;head&gt;
		&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;

		&lt;meta name="description" content="Descriptions..." /&gt;
		&lt;meta name="Keywords" content="Mots, clefs" /&gt;
&lt;link rel="stylesheet" href="design.css" _mce_href="design.css" type="text/css" media="screen, projection" /&gt;
&lt;link rel="shortcut icon" href="favicon.ico" _mce_href="favicon.ico"/&gt;
	&lt;/head&gt;
  	&lt;body&gt;
  	&lt;?php
		//Paramètres pour se connecter
		include('params.inc.php');

		//Connexion à la BDD
		$connect = mysql_connect(MYHOST, MYUSER, MYPASS)  or die ('Identifiants incorrects');
		mysql_select_db(MYDB) or die ('Base de données incorrecte');

		//Récupère le nombre total d'items
		$result = mysql_query('SELECT COUNT(*) FROM commentaires');
		$nbItems = mysql_fetch_array($result);
		$nbItems = $nbItems[0];

		$itemsParPage = 2 ;

		//Nombre de pages
		$nbPages = $nbItems/$itemsParPage;

		//Numéro de Page courante
		if(!isset($_GET['idPage']))
			$pageCourante = 1;
		elseif(is_numeric($_GET['idPage']) &amp;&amp; $_GET['idPage']&lt;=$nbPages)
			$pageCourante = $_GET['idPage'];
		else
			$pageCourante = $nbPages;

		//Calcul de la clause LIMIT
		$limitstart = $pageCourante*$itemsParPage-$itemsParPage;

		$requete = 'SELECT * FROM commentaires ORDER BY id LIMIT '.$limitstart.','.$itemsParPage.'';

		$result = mysql_query($requete);
		while($com_courant = mysql_fetch_assoc($result)){
			echo $com_courant['nom'].' '.$com_courant['texte'].'
&lt;hr /&gt;';

		}
		//Système de pagination
		require_once('class.pagination.php');
		Pagination::affiche('index.php','idPage',$nbPages,$pageCourante,2);
	?&gt;
	&lt;/body&gt;
&lt;/html&gt;

La partie PHP est dorénavant terminée, il ne reste plus qu’à styliser tout ça en CSS.

 

Etape 4 : La feuille de style CSS

Vous pouvez maintenant égayer un petit peu la pagination avec du CSS, voici un exemple de CSS sympa qui lui irait bien:

	.pagination {
				font-family:georgia;
				font-size:0.9em;
				margin:10px;
				padding:10px;
			}
			.pagination .courante {
				background:#32B1D0 none repeat scroll 0 0;
				border:1px solid #918A7B;
				color:white;
				border-radius:0.5em;
				-moz-border-radius:0.5em;
				margin-left:5px;
				padding:4px 8px;
				text-decoration:none;
			}
			.pagination .desactive {
				color:#918A7B;
				margin-left:5px;
				padding:3px 7px;
				text-decoration:none;
			}
			.pagination a {
				background:#f7f5ef none repeat scroll 0 0;
				background-image:url('background.png');
				background-repeat:repeat-x;
				border:1px solid #918A7B;
				color:black;
				margin-left:5px;
				border-radius:0.5em;
				-moz-border-radius:0.5em;
				padding:3px 7px;
				text-decoration:none;
			}
			.pagination a:hover {
				background:#ECE6D7 none repeat scroll 0 0;
				border:1px solid #555;
				color:#4B4438;
			}

36 commentaires

S'abonner au RSS des commentaires
  1. lgej
    Posté le 03/03/2012 à 7h30

    Bonjour,
    Pour un débutant, il est difficile de comprendre la structure du script php lorsque le programme de fonctionne pas. Les indentations ne sont pas visibles, et ne pas mettre les parenthèses pour les imbrications rend le script illisible.
    Merci pour le tutorial, mais je n’ai pas réussi à le faire fonctionner, donc je ne suis pas à son niveau pour corriger l’origine des messages type ‘manque ;’ (ponctuation).

  2. Thomas
    Posté le 09/09/2011 à 13h37

    Merci beaucoup pour ce tutoriel qui donne un très bon résultat ! Pour ceux qui ont le même problème que « Des », créez un fichier .htaccess et mettez simplement la ligne : php1

    En tout cas ça marche chez Free ;) En gros, on dit au serveur de free d’interpréter le site comme du PHP5 !

    Encore merci !

  3. sido
    Posté le 17/06/2011 à 7h28

    bonjour,
    est ce normal qu’on arrive pas à voir les démo?
    cordialement

  4. Blue
    Posté le 06/01/2011 à 21h26

    Salut à tous
    Merci pour ce super tuto.
    J’en viens maintenant à un tout petit problème concernant l’affichage.
    En fait à chaque fois que je clique sur un numéro de page, ça fait remonter en haut de page, je veux dire que je ne suis plus au niveau du systeme de pagination et qu’à chaque fois je dois utiliser l’ascenceur pour revenir aux résultats de la page.
    C’est un peu lassant à la longue.
    Vous pouvez m’aider svp?

  5. Allan
    Posté le 11/06/2010 à 11h58

    et merci d’avance , je continue a chercher de mon coté

    allan
    ( ps j’ai envoyé le message un peu trop rapidement dsl )

  6. Allan
    Posté le 11/06/2010 à 11h56

    bonjour tout le monde,
    felicitation en tout cas pour le tuto , il est genial…
    Seulement j’ai un petit probleme…je l’integre tout , j’ai aucun probleme. J’ai géré une interface admin qui me permet d’ajouter des news afin de simplifier la mise a jour du site. et pour eviter d’avoir une page de trois pieds de long en rajoutant ces " blocs "’ j’ai utilisé la pagination.
    J’ai parametré de sorte a n’avoir que trois blocs par page. Seulement si j’ai que 4 blocs.. et bin sur ma deuxieme page, il va m’afficher mon bloc n’2 n’3 et n’4. Je me retrouve donc sur mon site avec les blocs 2 et 3 en double..et moi sur ma deuxieme page j’aimerai que mon bloc 4.. est ce possible ?

Laisser un commentaire

Votre e-mail ne sera jamais publié ni communiqué. Les champs obligatoires sont indiqués par *

*
*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>