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. kiwi
    Posté le 26/05/2010 à 17h15

    HONTE A MOI
    desolé c’était vraiment tout simple

    $requete = ‘SELECT * FROM commentaires ORDER BY id DESC LIMIT ‘.$limitstart.’,’.$itemsParPage. »;

  2. kiwi
    Posté le 26/05/2010 à 16h51

    bonjour alors la chapeau ,c’est le tutoriel le plus complet que j’ai vu actuelement sur la pagination,je suis vraiment ravie d’être tomber dessus encore bravo..

    J’ai un petit souci quand même mais la c’est de la faute a mon incompétence lol

    si je veux que la dernière news enregistrer soit la première sur la première page et non l inverse parceque la ça enregistre la dernière news sur la dernière page ..
    C’est possible ?ou est que je le glisse mon order by

    Merci d’avance pour la réponse si il y a.

  3. Diana
    Posté le 24/05/2010 à 15h48

    Bravo pour votre site, très bons tutos wink

  4. milounis
    Posté le 22/01/2010 à 23h55

    un grand merci pour le tuto, il est parfait c exactement se que je voulé comme résultat avec ma pagination sur mes pages de résultats, chapeau pour son auteur, et encore merci

  5. Ninouparadise
    Posté le 29/10/2009 à 10h17

    Salut, Moi j’ai un pb, la pagination ne s’affiche pas… Comment ça se fais?

  6. François
    Posté le 18/09/2009 à 0h47

    Salut!
    C’est probablement du à ton serveur, vérifie bien que tu es en PHP 5…

  7. Des
    Posté le 15/09/2009 à 12h38

    Salut! Tout dabord merci pour ce tuto! J’ai testai le script mais j’ai une erreur Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in /home/sites/pagination/class.pagination.php on line 17.
    Ca correspond a cette ligne:
    public static function affiche($chemin,$nomget,$total,$courante=1,$affichage=2){

    Je vois pas d’ou ca viens. As tu une idée?

    Merci

  8. François
    Posté le 12/09/2009 à 12h03

    Salut! Y’a aussi des solutions pour lire des fichiers texte en PHP et lire chaque ligne une par une … essaye de voir sur php.net les fonction fopen et fread…a+

  9. Fabinounours
    Posté le 11/09/2009 à 9h53

    Bonjour, déjà merci pour ce code.
    Mais j’aurais une question. Ne serait-il pas possible de faire la même chose mais au lieu que ce soit à partir d’une BDD, le faire à partir d’un fichier CSV.
    Je ne sais pas trop comment m’y prendre, mais personnellement je dois effectuer la même chose sur un fichier csv de 200 000 lignes. Il me faut un affichage rapide. J’avais pensé exploiter votre solution..

  10. maya
    Posté le 31/08/2009 à 6h23

    merci samidev j’avais le même problème que toi et j lé résolut grâce a ta fonction ceil

  11. samidev
    Posté le 21/06/2009 à 19h12

    ouffff après des heures de travail j’ai réussie à ajouter un autre paraméte dans le lein des pages

    voici la partie à modifier dans la class.pagination.php
    public static function lien($chemin,$texte,$parametre= »,$valeur= »){

    $cat=$_GET['cat'];

    $lien = ‘<a href="’.$chemin;

    if(!empty($parametre))
    $lien .= ‘?’.$parametre.’=’.$valeur.’&cat=’.$cat;

    $lien .= ‘">’.$texte.’</a>’;

    return $lien;
    }

  12. sami dev
    Posté le 21/06/2009 à 18h53

    bonjour fronçois scp comment ajouter un autre paramétre sur le lein des pages
    comme prodcat.php?idpage=2&cat=portable

  13. samidev
    Posté le 20/06/2009 à 0h02

    lol wéééééééééé j’ai resolue le problème avec la fonction ceil wink merciiiii françois
    en faite moi samir du maroc

  14. samidev
    Posté le 19/06/2009 à 23h54

    dsl pour le dérangement , j’ai fait echo $nbpages et il m’a donner 3.5 c’est ça le problème il me donne un nombre de type float

  15. François
    Posté le 19/06/2009 à 23h41

    Rebonjour!

    Vérifie bien ta variable $nbPages… si elle vaut vraiment 3 c’est qu’il y’a un soucis dans ton calcul de $nbPages…Sinon je ne vois pas…

  16. samidev
    Posté le 19/06/2009 à 23h28

    merci françois , ça marche mais j’ai un petit soucie le dernier enregistrement ou la dernière page son numéro ne s’affiche pas j’ai 4 page alor que dans la pagination il n’ya que 1.2.3

  17. François
    Posté le 19/06/2009 à 21h51

    Il donnera pas 0 car la multiplication est prioritaire par rapport à la soustraction, donc ca équivaut à ca: ($pageCourante*$itemsParPage)-$itemsParPage;
    Ce qui vaudrait 0 uniquement si $pageCourante = 1 ce qui est logique puisque sur la première page on affiche à partir du début (0)
    Sinon il faudrait que $itemsParPage = 0… et là je ne vois pas l’interêt^^

  18. samidev
    Posté le 19/06/2009 à 18h25

    prk ce code $limitstart = $pageCourante*$itemsParPage-$itemsParPage;
    sa donnera 0 !!

  19. samidev
    Posté le 19/06/2009 à 18h23

    joliu tutorial j’ai des difficultés en poo je suis debutant dans le php 5 merci pour ce tuto

  20. T.OM
    Posté le 09/06/2009 à 15h33

    Ok merci, je vais voir ça.

  21. François
    Posté le 09/06/2009 à 12h28

    Ce que tu peux faire, c’est d’aller voir ce tutoriel: http://grafikart.fr/tutoriels/video/gerer-news-php-43
    Tres bien expliqué et en vidéos!
    Tchao!

  22. T.OM
    Posté le 09/06/2009 à 11h43

    J’ai oubilié de dire que les 10-20 pages sont dans la même catégorie et donc concernées entre elles.

  23. T.OM
    Posté le 09/06/2009 à 11h41

    C’est un site de collection des objets et la plupart des catégorie a entre 10-20 pages,

    donc d’après ce que tu dis, j’imagine qu’il faut faire une pagination en PHP pour etre mieux.

    le souci c’est que je ne connais rien en PHP, tu pourrais m’aider s’il te plait ? ou tu as un Tuto pour moi ?

    Je te remercie bcp d’avance.

  24. François
    Posté le 09/06/2009 à 11h20

    En fait c’est toujours mieux d’éviter de faire des pages statiques, au niveau de la maintenance du site c’est un peu la galère.
    Après si ce sont des pages qui n’ont rien à voir entre elles je ne vois pas trop l’intérêt de la pagination. Ce que tu peux faire c’est quand même de mettre le contenu de tes pages dans une base de donnée, surtout si tu en as 20…

  25. T.OM
    Posté le 09/06/2009 à 9h31

    Merci pour ta réponse,

    En faite, je voudrais savoir s’il est plus utile de faire une pagination ou non pour une partie de mon site qui a 10-20 pages statique

  26. François
    Posté le 09/06/2009 à 1h02

    Salut, en fait j’ai pas trop compris ce que tu demandais, tu veux mettre des liens vers des pages statiques dans ta pagination? Si c’est ca, il faudrait retoucher le code car il n’est pas prévu pour ca à la base, il sert juste à a paginer des données selon une table SQL.

  27. T.OM
    Posté le 08/06/2009 à 22h34

    Bonsoir à tous,

    Je voudrais savoir si possible de mettre plusieurs pages html déjà existant en pagination ou c’est inutil,

    et si c’est faisable pourriez-vous m’expliquer comment faire s’il vous plait, car je ne connais rien en PHP et je débute en XHTML & CSS.

    Merci bcp & A+.

  28. NaetoH
    Posté le 24/05/2009 à 3h03

    En faite j’ai reussi, il fallais transformer la commande :

    Pagination::affiche(‘commentaires.php’,'idPage’,$nbPages,$pageCourante,2);

    en :

    Pagination::affiche(‘commentaires.php’,'id=’.$id.’ idPage’,$nbPages,$pageCourante,2);

  29. NaetoH
    Posté le 24/05/2009 à 2h46

    Moi j’ai un petit problème avec ce code, je l’ai modifier un petit peut et j’ai remarquer un bug.

    Je l’utilise pour un systeme de commentaires, et lorsque j’ajoute un commentaires ma page et egal a commentaires.php?id=26 , 26 et le numero de la news (je lie l’id de la table news a news_id de la table comment.

    Aucun problème tous marche avec la modif que j’ai fait.

    Sauf que lorsque je veut utiliser la pagination la page passe de commentaires.php?id=26 a commentaires.php?idPage=2 , alors que moi j’aurai besoin de commentaires.php?id=26&idPage=2 mais je n’arrive pas a le modifier.

  30. Jasse29
    Posté le 02/05/2009 à 2h02

    Bonsoir,

    On retrouve dans ce tutoriel un contenu complémentaire au tutoriel vidéo que l’on retrouve sur le blog de GrafikArt.

    Intéressant.

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>