Aide sur un tableau et une boucle (avec modulo).

Signaler
-
 Spinner -
Bonjour,

Après avoir pas mal galéré, j'ai réussi avec un peu d'aide à faire un script en PHP qui affiche les résultats d'une base de données de la manière suivnte: dans un tableau avec trois lignes maximum puis avec un nouveau tableau qui se crée une fois la limite des trois lignes atteintes et ainsi de suite.

Voici le code de la partie affichage:

$i=0;
while($data=mysqli_fetch_array($requete1)) {
if($i%3==0)
echo "Mes résultats : <table><tr><td>".$data['NOM']."</td>etc.";
if ($i%3==2)
</tr>
$i++;
}
if($i%3!=0)
echo "</tr>";
echo "</table>;

Cela fonctionne mais j'ai du mal à comprendre - et du coup à apprendre ce point précis. En effet, je sais que le modulo correspond au reste d'une division euclidienne, pas de souci. Ce que je comprends moins voire pas du tout, c'est pourquoi on utilise ça à ce moment-là en PHP. Quel est le rapport?
Ce que je ne comprends également pas, c'est la différence de stade dans le code entre le ==2 et le !=0. Un script dont je me suis inspiré a conseillé de mettre ce !=0 après la boucle, ce que j'ai fait. Mais lorsque je l'enlève ça marche quand même. Donc à quoi cela sert-il concrètement?
Je vous serais très reconnaissant de m'apporter vos lumières sur ce point.

3 réponses

Messages postés
2556
Date d'inscription
lundi 11 février 2013
Statut
Membre
Dernière intervention
15 septembre 2021
461
Bonjour,

Tu souhaites grouper les résultats dans un tableau par groupe de 3, or la boucle while parcours chaque élément un par un.
Il faut donc dans la boucle savoir pour chaque élément si celui-ci est le premier ou le dernier élément d'un groupe de 3 afin d'ouvrir ou fermer les balises <tr> pour chaque groupe de 3.

Le modulo permet de savoir pour chaque élément à quelle position il se trouve dans un groupe de 3 éléments.

Ton code actuel ne semble pas correct car tu ouvres une balise table pour chaque premier élément d'un groupe de 3, il faudrait ouvrir la balise table avant ta boucle et ouvrir/fermer les balises tr en fonction du résultat du modulo.

Puisqu'un exemple vaut mieux que milles mots, tu peux éventuellement afficher la position de chaque élément via modulo pour mieux comprendre l'idée (j'utilise un tableau php mais le principe est similaire pour un mysqli_fetch) :
$myArray = ['elem1', 'elem2', 'elem3', 'elem4', 'elem5', 'elem6'];

$i = 0;

echo '<pre>';
while ($i < sizeof($myArray)) {
    echo 'Tour n° ' . $i . ' : ' . 'L\'élément ' . $myArray[$i] . ' est à la position ' . $i % 3 . ' dans son groupe de 3 éléments' . "\n";
    $i++;
}
echo '</pre>';


Une fois cette idée comprise, tu peux donc gérer l'ouverture/fermeture des balises td par exemple comme ceci :
$myArray = ['elem1', 'elem2', 'elem3', 'elem4', 'elem5', 'elem6'];

$i = 0;
echo '<table>';
while ($i < sizeof($myArray)) {
    if ($i % 3 == 0) {
        // premier élement d'un groupe de 3, on ouvre une nouvelle ligne
        echo '<tr>';
    }
    
    echo '<td>' . $myArray[$i] . '</td>';
    
    if ($i % 3 == 2) {
        // dernier élément d'un groupe de 3, on ferme la ligne
        echo '</tr>';
    }
    
    $i++;
}

echo '</table>';


Cet exemple fonctionne correctement si le nombre d'élément dans le tableau est un multiple de 3, dans le cas contraire la dernière balise tr n'est pas correctement fermée (je t'invite à ajouter un élément dans le tableau et voir le code html généré pour t'en rendre compte).
Il faut donc ajouter une condition après notre boucle pour fermer correctement la balise tr si le dernier élément dans la boucle n'est pas le dernier élément d'un groupe de 3, soit :

<?php

$myArray = ['elem1', 'elem2', 'elem3', 'elem4', 'elem5', 'elem6', 'elem7'];

$i = 0;
echo '<table>';
while ($i < sizeof($myArray)) {
    if ($i % 3 == 0) {
        // premier élement d'un groupe de 3, on ouvre une nouvelle ligne
        echo '<tr>';
    }
    
    echo '<td>' . $myArray[$i] . '</td>';
    
    if ($i % 3 == 2) {
        // dernier élément d'un groupe de 3, on ferme la ligne
        echo '</tr>';
    }
    
    $i++;
}

if ($i % 3 != 2) {
    // si le dernier élément n'est pas le dernier élément d'un groupe de 3 (par exemple si on a 7 éléments) -> on ferme la dernière ligne
    echo '</tr>';
}

echo '</table>';
Franchement merci beaucoup !

En général je parviens toujours à me débrouiller par moi-même mais cette histoire de modulo commençait vraiment à me tracasser. La manière dont vous l'avez présenté approche de la perfection car je trouve ça limpide désormais.
C'est vraiment super d'avoir pris le temps de bien expliquer et surtout d'avoir décomposé la chose ainsi que vous l'avez fait. En refaisant chacun des scripts ça m'a permis de réellement comprendre.

Une dernière question cependant s'il vous plaît: la formule que vous avez employé "sa position par rapport à un groupe de trois" est tout à fait ce dont j'avais besoin pour comprendre. Mais ce que je ne comprends pas c'est le rapport entre cela et l'opération mathématique qui fait que c'est le reste d'une division. Est-ce que ça n'a aucun rapport ou est-ce que quelque chose m'échappe ?
Messages postés
2556
Date d'inscription
lundi 11 février 2013
Statut
Membre
Dernière intervention
15 septembre 2021
461
Il y a bien un rapport puisque c'est effectivement l'opération $i modulo 3 qui permet de savoir pour chaque élément $i sa position dans un groupe de 3.

Puisque l'opération $i modulo 3 retourne le reste d'une division par 3, celle-ci va toujours retourner une des 3 valeurs suivantes :
- la valeur 0 si $i est égal à 0 ou 3 ou 6 ou 9 etc... (les premiers éléments de chaque groupe de 3)
- la valeur 1 si $i est égal à 1 ou 4 ou 7 ou 10 etc... (les deuxièmes éléments de chaque groupe de 3)
- la valeur 2 si $i est égal à 2 ou 5 ou 8 ou 11 etc... (les troisièmes éléments de chaque groupe de 3)
Alors là c'est vraiment parfait. J'avoue que j'étais un peu fâché avec les maths pur jus, ceci doit expliquer cela... Mais dorénavant c'est très clair, merci beaucoup, vraiment !