Bonjour à tous...

J'ai créé pour un gite une page "tourisme.php" qui affiche les activités à faire dans la région. La partie qui affiche les données
en provenance d'une base de données fonctionne parfaitement, y compris le filtre par type d'activité...

Si je post ici c'est que je ne sais pas comment m'y prendre pour n'afficher que 4 activités par page et afficher en bas de page un
index qui ressemble à << 1 2 3 >> selon le nombre de pages nécessaires...

Si je pars sur une boucle FOR avec une variable globale
en guise de compteur, j'ai bon ? Ca me semble pas être le
bonne méthode !
Voici déja mon bout de code qui fonctionne :

<?php                            
while ($data=$req->fetch(PDO::FETCH_OBJ)) { ?>
<img src="gestion/photos/<?= $data->photo ;?>" alt="" title="" width="244" height="196" />
<div>
    <?= $data->type ;?>  |  <?= $data->kms ;?> / <?= $data->temps ;?>
</div>
<h2>
    <?= $data->titre ;?>
</h2>
<p style="text-align:justify;">
    <?= $data->infos ;?>
</p>
<?php
} 
?>

MERCI d'avance pour vos conseils

21 réponses


Carouge10
Réponse acceptée

Il suffit d'ajouter le limit

// Récupération des enregistrements correspondant à la catégorie :
    $premierMessageAafficher = ($page - 1) * 4;
    $requete2 = $DB->query("SELECT * FROM tourisme WHERE type = '$categorie' ORDER BY titre LIMIT ".$premierMessageAafficher . ", 4");
<ul class="pagination">
     <!--<li class="first"><a href="#">Messages précédents</a></li>-->
     <li class="active"><a href="#">1</a></li>
     <li><a href="#">2</a></li>
     <li><a href="#">3</a></li>
     <li><a href="#">4</a></li>
     <li><a href="#">5</a></li>
     <li><a href="#">6</a></li>
     <li><a href="#">7</a></li>
     <li><a href="#">8</a></li>
     <li class="last"><a href="#">Anciens messages</a></li>
</ul>

Tu comptes le nombre d'article total que tu divises par le nombre d'articles que tu veux par page. De cette façon tu obtiens de quoi mettre en place ta pagination. Ensuite tu construis ta requête SQL en fonction de la page sur laquelle se trouve l'utilisateur avec la fonction LIMIT de MySQL :)

Pourquoi faire compliqué quand on peut faire simple !

Merci Cyprien, j'essaie tout de suite et reviens par ici si j'arrive pas à
ordonner ma syntaxe !

Je t'en prie. Crois en mon expérience, on cherche tout le temps à faire Compliqué alors que la solution est souvent simple ;)
Tu me dis si tu y arrive ou si tu as besoin d'aide.

Suis-je obligé d'avoir deux requêtes pour ce que je veux ?
(Une pour compter, une autre pour remonter toutes mes infos)

Ceci ne fonctionne pas :

$req = $DB->query($sql);
$res = $req->fetchAll();
echo 'Cette requête retourne '.count($res). ' enregistrements.';

Pour infos, je récupère mes données avec ça : <?= $data->titre ;?>

J'ai trouvé ça qui marche !

$req = $DB->query($sql);
$count = $req->rowCount();
echo 'Cette requête retourne '. $count . ' enregistrements.';

Je veux dire que j'ai mes données qui s'affichent et le nombre d'articles concernés
par la requête !
J'avance !

Bon, j'ai bien travaillé : presque tout fonctionne...
Je me suis aidé d'un tuto trouvé sur Internet pour un livre d'or, il était en Php/Sql "classique", je l'ai adapté
à mon PDO...
J'ai encore un truc qui cloche :
Mon affichage dans la partie filtrée sur les catégories ne tient pas compte de 4 articles par page,
et pour cause, je ne sais pas écrire la syntaxe LIMIT car trop de ' ou de ".....

Voici mon code, si cela pouvait inspirer quelqu'un !

require ('gestion/connexion.php');

if (isset($_GET['cat'])){
    $categorie = $_GET['cat'];
    // Calcul du nombre d'enregistrements dans la table pour une catégorie donnée : 
    $requete1 = $DB->query("SELECT COUNT(*) AS total FROM tourisme WHERE type = '$categorie'");
    $reponse1 = $requete1->fetch();
    $total = $reponse1['total'];

    // Calcul du nombre de pages à créer pour 4 articles par page : 
    $nombredepages = ceil($total/4);

    // On récupère le n° de la page actuelle 
    if (isset($_GET['page'])){
        $page = $_GET['page']; // On récupère le numéro de la page indiqué dans l'adresse
    }
    else { // La variable n'existe pas, c'est la première fois qu'on charge la page
        $page = 1; // On se met sur la page 1 (par défaut)
    }
    // On calcule le numéro du premier message qu'on prend pour le LIMIT de MySQL
    $premierMessageAafficher = ($page - 1) * 4;
    // Récupération des enregistrements correspondant à la catégorie :
    $requete2 = $DB->query("SELECT * FROM tourisme WHERE type = '$categorie' ORDER BY titre");
}
else {
    //Calcul du nombre total d'enregistrements dans la table : 
    $requete1 = $DB->query('SELECT COUNT(*) AS total FROM tourisme');
    $reponse1 = $requete1->fetch();
    $total = $reponse1['total'];

    // Calcul du nombre de pages à créer pour 4 articles par page : 
    $nombredepages = ceil($total/4);

    // On récupère le n° de la page actuelle 
    if (isset($_GET['page'])){
        $page = $_GET['page']; // On récupère le numéro de la page indiqué dans l'adresse
    }
    else { // La variable n'existe pas, c'est la première fois qu'on charge la page
        $page = 1; // On se met sur la page 1 (par défaut)
    }

    // On calcule le numéro du premier message qu'on prend pour le LIMIT de MySQL
    $premierMessageAafficher = ($page - 1) * 4;
    $requete2 = $DB->query('SELECT * FROM tourisme ORDER BY titre LIMIT ' . $premierMessageAafficher . ', ' . '4');
}

La dernière requête sera plus simple ainsi :

$requete2 = $DB->query('SELECT * FROM tourisme ORDER BY titre LIMIT ' . $premierMessageAafficher . ', 4');

Effectivement, j'ai corrigé, merci !

Je ne sais pas si techniquement, ce que je veux faire est possible...
Quand on choisi une catégorie d'articles, par exemple "Villages typiques" , la partie filtre fonctionne,
je n'affiche que des "Villages typiques" mais je me retrouve avec plus de 4 articles par page : je ne sais
pas écrire la syntaxe de ma requète avec la variable $catégorie au milieu...Ca fait une heure que j'essaie
d'échapper les ' et les " mais je ne sais pas comment faire.

D'autre part, la partie en bas de page << 1 2 >> ne sait pas conserver le fait que nous sommes
avec un filtre sur une catégorie d'articles... La base de données contient 5 articles "Villages typiques".
Ils s'affichent tous les 5 sur la première page alors que j'ai bien un lien pour la page 1 et 2 (5 articles en tout
à raison de 4 par page = 2 pages à afficher) : logique, mais si on clique sur 2 on se retrouve avec tous
les articles de la base ! normal là aussi, mais je n'ai aucune idée de comment tourner ça !

<ul class="style1">
     <li><a href="tourisme.php?cat=Artisanat">Artisanat</a></li>
     <li><a href="tourisme.php?cat=Curiosité">Curiosité</a></li>
     <li><a href="tourisme.php?cat=Musée">Musée</a></li>
     <li><a href="tourisme.php?cat=Village typique">Village typique</a></li>
</ul>
<?php
 if($nombredepages > 1) {                                    
      echo '<ul class="pagination">'; 
      for ($i = 1 ; $i <= $nombredepages ; $i++) {
          echo '<li><a href="tourisme.php?page=' . $i . '">' . $i . '</a></li>';
     }
     echo '</ul>'; 
}?>

Pour la 1ère partie, montrer-moi une requête car celle que vous aviez est correcte.

Pour la seconde partie, il faut prendre du recul et revoir le lien.... ne faudrait-il pas le changer....

Les requêtes sont les mêmes pour tous les articles et pour les catégories d'articles, c'est bien
là le problème. Je sais faire une requête avec une LIMIT de 4 articles, je sais faire une requête
avec une certaine catégorie d'articles, mais je ne sais pas faire une requête avec une certaine
catégorie d'articles LIMITée à 4 affichages par page :

Code pour 4 articles seulement par page :

// On calcule le numéro du premier message qu'on prend pour le LIMIT de MySQL
    $premierMessageAafficher = ($page - 1) * 4;
    $requete2 = $DB->query('SELECT * FROM tourisme ORDER BY titre LIMIT ' . $premierMessageAafficher . ', 4');

Code pour une catégorie d'articles seulement :

// Récupération des enregistrements correspondant à la catégorie :
    $premierMessageAafficher = ($page - 1) * 4;
    $requete2 = $DB->query("SELECT * FROM tourisme WHERE type = '$categorie' ORDER BY titre");

J'aimerai bien trouver des explications sur quand mettre ', quand mettre ", quand mettre \' ou à quoi sert ` (ALT Gr 7)....
Mes requêtes sont correctes grâce à la colorisation de Sublime Text, je préférerai qu'elle soit bonne parce que je comprends
pourquoi tel ou tel caractère utiliser !

Parfait Carouge, ça fonctionne comme je veux !
C'est cette syntaxe que je ne maitrise pas => ".$premierMessageAafficher . "

Il ne me reste plus que les liens bas de page pour afficher la page n° 2 pour voir mon
5° article tout seul, sauf que page 2 pointe vers la page 2 de tous les articles !

<?php
     if($nombredepages > 1) {
          echo '<ul class="pagination">';
          for ($i = 1 ; $i <= $nombredepages ; $i++) {
               echo '<li><a href="tourisme.php?page=' . $i . '">' . $i . '</a></li>';
          }
     echo '</ul>';
}?>

Je pense qu'il faut intégrer un if pour indiquer si on est en affichage classique ou
affichage filtré sur une catégorie...

Pour le filtre, le if est la solution sur la création de la requête mais pour la pagination, il y a plus simple

(Merci pour la doc très utile sur les quotes)
En ce qui concerne mon code, j'ai beau tourner le truc dans tous les sens, tu
m'intrigues en me disant que l'on peut faire plus simple !

Je fais ici un if($nombredepages > 1) pour m'assurer qu'on a bien un résultat et
qu'il necessite au moins 2 pages, sinon aucun intérêt d'afficher la pagination.

Ensuite j'ai besoin de href="tourisme.php?page=' . $i pour passer en paramètre GET
la page sur laquelle l'utilisateur souhaite aller et ainsi générer la bonne requête...

Enfin j'affiche . $i . pour le visiteur...

Au passage, j'aimerai bien bloquer la page sur laquelle on est actuellement et lui passer
un attribut css pour la distinguer visuellement des pages actives...

<li class="active"><a href="#">1</a></li>

C'est un peu bourin ça non ?
Bon, ça a le mérite de fonctionner !

<?php
if($nombredepages > 1) {                                    
     echo '<ul class="pagination">'; 
     for ($i = 1 ; $i <= $nombredepages ; $i++) {
          if (isset($_GET['page']) && $i ==$_GET['page']) {
               echo '<li class="active"><a href="#">' . $i . '</a></li>';
          }
          else {
               echo '<li><a href="tourisme.php?page=' . $i . '">' . $i . '</a></li>';
          }
     }
     echo '</ul>'; 
 }?>

Pour l'utilisation des quotes, Grafikart y à mis son grain de sel en vidéo
Personelement j'ai pris l'habitude de mettre des doubles quote pour du code PHP et des simple quotes pour du HTML :

// Ton
echo '<li><a href="tourisme.php?page=' . $i . '">' . $i . '</a></li>';
// se simplifi
echo "<li><a href='tourisme.php?page=$i'>$i</a></li>";

Merci nebjix pour le lien vidéo...
Subsiste quelques zones d'ombre comme le ` qui n'est pas abordé.
D'autre part, sans aide j'aurai eu du mal à rédiger cette requête :

$requete2 = $DB->query("SELECT * FROM tourisme WHERE type = '$categorie' ORDER BY titre LIMIT ".$premierMessageAafficher . ", 4");

notamment les " à la fin....

En tout cas, merci à vous deux pour votre aide !
J'ai un code qui pourrait être optimisé, mais il fonctionne :

<?php
require ('gestion/connexion.php');
$message = ''; // Création de la variable pour afficher un message si aucun résultat trouvé
if (isset($_GET['cat'])){      //Sommes nous sur un affichage d'une catégorie particulière ?
    $categorie = $_GET['cat'];
    // Calcul du nombre d'enregistrements dans la table pour une catégorie donnée :     
    $requete1 = $DB->prepare("SELECT COUNT(*) AS total FROM tourisme WHERE type = :categorie");
    $requete1->execute(array(':categorie' => $_GET['cat']));
    $reponse1 = $requete1->fetch();
    $total = $reponse1['total'];
    if ($total==0) {
        $message ='Aucun article trouvé pour cette catégorie, désolé !';
    }

    // Calcul du nombre de pages à créer pour 4 articles par page : 
    $nombredepages = ceil($total/4);

    // On récupère le n° de la page actuelle 
    if (isset($_GET['page'])){
        $page = $_GET['page']; // On récupère le numéro de la page indiqué dans l'adresse
    }
    else { // La variable n'existe pas, c'est la première fois qu'on charge la page        
        $page = 1; // On se met sur la page 1 (par défaut)
    }

    // Récupération des enregistrements correspondant à la catégorie :
    $premierMessageAafficher = ($page - 1) * 4;    
    $requete2 = $DB->query("SELECT * FROM tourisme WHERE type = '$categorie' ORDER BY titre LIMIT ".$premierMessageAafficher . ", 4");
}
else {  //aucune catégorie selectionnée, on affiche tout à raison de 4 articles par page
    //Calcul du nombre total d'enregistrements dans la table : 
    $requete1 = $DB->query('SELECT COUNT(*) AS total FROM tourisme');
    $reponse1 = $requete1->fetch();
    $total = $reponse1['total'];

    // Calcul du nombre de pages à créer pour 4 articles par page : 
    $nombredepages = ceil($total/4);

    // On récupère le n° de la page actuelle 
    if (isset($_GET['page'])){
        $page = $_GET['page']; // On récupère le numéro de la page indiqué dans l'adresse
    }
    else { // La variable n'existe pas, c'est la première fois qu'on charge la page
        $page = 1; // On se met sur la page 1 (par défaut)
    }

    // On calcule le numéro du premier message qu'on prend pour le LIMIT de MySQL
    $premierMessageAafficher = ($page - 1) * 4;
    $requete2 = $DB->query('SELECT * FROM tourisme ORDER BY titre LIMIT ' . $premierMessageAafficher . ', 4');
}

?>

<?php 
// Affichage des données : 
     echo '<h2>' . $message . '</h2>';
     while ($data=$requete2->fetch(PDO::FETCH_OBJ)) { ?>
          <div class="media">
               <div class="media-image pull-left">
                    <img src="gestion/photos/<?= $data->photo ;?>" alt="" title="" class="media-object"  width="244" height="196" />
               </div>
               <div class="media-body">
                    <h2 class="media-heading"><?= $data->titre ;?></h2>
                    <div class="green"><?= $data->type ;?>  |  <?= $data->kms ;?> / <?= $data->temps ;?> </div>
                    <p style="text-align:justify;"><?= $data->infos ;?></p>
               </div>
               </div>
               <?php
} ?>

Et pour la pagination :

<?php

if($nombredepages > 1) {                // Si + d'une page : pagination, sinon on affiche rien !                    
     echo '<ul class="pagination">'; 
     for ($i = 1 ; $i <= $nombredepages ; $i++) {
          if (isset($_GET['page']) && $i ==$_GET['page']||$page==1 && $i ==1) {
               echo '<li class="active"><a href="#">' . $i . '</a></li>';
          }
          else {
               if (isset($categorie)){  // Pour renseigner la requête si on filtre sur une catégorie
                    echo "<li><a href='tourisme.php?page=$i&cat=$categorie'>$i</a></li>";
               }
               else { // sinon on est sur un affichage de toute la base
                    echo "<li><a href='tourisme.php?page=$i'>$i</a></li>";
                }
           }
      }
     echo '</ul>'; 
                                }?>