Les boucles en PHP

Le principe des boucles
Si on veut afficher tous les clients contenus dans notre base de données dans un liste à puces, par exemple, il va falloir interroger notre base de données puis afficher les informations.
Lorsqu'on interroge notre base et qu'on récupère les informations, on récupère, en quelque sorte, un gros tableau, comme celui-ci :
| Nom | Prénom |
|---|---|
| Masson | Sébastien |
| Chantriaux | Mathieu |
| L-B | Lubin |
Si on ne s'intéresse qu'aux prénoms, on va donc récupérer une colonne. Or, dans cette colonne, les prénoms sont chacun dans une case du tableau. Un tableau en PHP c'est un array.
$prenom = array("Sébastien","Mathieu","Lubin");
Rappel : dans les array indicés, on commence à compter à 0. Donc $prenom[0] équivaut à Sébastien.
La variable $prenom est l'entête de colonne et chaque cellule un élément du array.
Pour afficher chaque élément dans un élément de liste non ordonnée, on devra alors écrire le code suivant :
<ul>
<li><?= $prenom[0] ?></li>
<li><?= $prenom[1] ?></li>
<li><?= $prenom[2] ?></li>
</ul>
Ce qui reviendrait à écrire chaque prénom à la main.
Quand on analyse ce code on s'aperçoit qu'il y a une répétition :
<li><?= $prenom[] ?></li>
Seul ce qu'il y a entre les crochets change. On a 0 puis 1 puis 2 ... C'est cette automatisation qu'une boucle va nous permettre d'effectuer. On va lui montrer comment écrire cette ligne qui se répète, quels sont les éléments à changer sur chaque ligne et comment les changer.
La boucle for
La boucle for s'utilise quand on a un contexte connu. On sait où commence la boucle, où elle finit et comment elle doit évoluer.
Elle prend trois paramètres, dans cet ordre précis :
- le point de départ
- le point de fin, de sortie de la boucle
- l'incrément, c'est-à-dire le rythme de lecture
Dans notre contexte de liste de prénoms, on sait qu'on veut afficher tous les prénoms donc de l'indice 0 à l'indice x.
for($i=0; $i<count($prenom); $i++){
echo "<li>$prenom[$i]</li>";
}
- $i=0 est le point de départ car on commence à lire notre array au début, donc au premier élément.
- $i
- $i++ est l'incrément. On lit tous les éléments, de 1 en 1.
la fonction count() permet de compter le nombre d'élément d'un array.
$i++ revient à écrire $i = $i + 1 mais c'est plus court ... $i-- existe également.
Pour que les choses soient bien claires :
En point de fin on indique que $i doit être inférieur au nombre d'éléments du array. Cela n'exclue pas le dernier.
Pourquoi ?
Parce que, dans notre exemple, on a 3 éléments dans le array. Mais le premier a l'indice 0, le second l'indice 1 et le dernier l'indice 2. On s'arrête donc bien à 2 et pas 3. Même si le tableau compte trois éléments.
Toujours un peu compliqué quand on change la façon de compter. Mais c'est juste une question d'entraînement :
De manière à rendre la syntaxe plus lisible, une variante est désormais possible.
for($i=0; $i<count($prenom); $i++) :
echo "<li>$prenom[$i]</li>";
endfor;
L'accolade ouvrante est remplacée par : et l'accolade fermante est remplacée par endfor;
La boucle while
La boucle WHILE fonctionne sur le même principe que la boucle FOR. Elle a les mêmes trois paramètres mais ils sont placés à des endroits différents.
Sur un rendu purement algorithmique, on pourrait y voir la même chose. Dans la pratique c'est un peut différent car sa signification est bien "tant que". Donc tant que l'internaute ne donnne pas son nom, on le renvoie sur le formulaire. Tant que le mot de passe n'est pas bon, on le lui redemande ...
echo '<ul>';
$i=0; // notre point de départ
while($i < count($prenom)){ // le point de fin
echo "<li>$prenom[$i]</li>";
$i++; // l'incrément
}
echo '</ul>
Attention à ne pas oublier l'incrément sinon c'est une boucle infinie...
De manière à rendre la syntaxe plus lisible, une variante est désormais possible.
echo '<ul>';
$i=0; // notre point de départ
while($i < count($prenom)): // le point de fin
echo "<li>$prenom[$i]</li>";
$i++; // l'incrément
endwhile;
echo '</ul>
L'accolade ouvrante est remplacée par : et l'accolade fermante est remplacée par endfor;
La boucle foreach
La boucle FOREACH est la grande spécialiste des tableaux. Elle permet de ne pas avoir à utiliser l'indice d'un élement pour l'afficher. Mais comme son nom l'indique c'est "pour chaque élément du tableau".
echo '<ul>';
foreach($prenom AS $p){
echo "<li>$p</li>";
}
echo '</ul>';
Très pratique et plus facile à écrire, elle prend, tour à tour, chaque élément du tableau, le place dans une variable temporaire (ici j'ai choisi $p) qui est donc disponible pour notre script. Jusqu'à ce qu'elle soit réaffectée au passage suivant de la boucle.
La même syntaxe courte existe que pour les boucles FOR et WHILE.
echo '<ul>';
foreach($prenom AS $p) :
echo "<li>$p</li>";
endforeach;
echo '</ul>';
La boucle do while
La boucle DO WHILE est une dérivée de la boucle WHILE. Son nom vous donne sa spécificité. Elle fait ... tant que.
C'est-à-dire qu'elle fait, au moins une fois, tant que le test logique n'est pas réalsié.
$i=100;
do{
echo $i.'- ';
}
while($i<150);
Ici on affiche les chiffres de 100 à 150. Ca ressemble un peu à for ou while. Mais sa spécificité c'est de s'exécuter au moins une fois, car on commence avec l'instruction DO.
$i=100;
do{
echo $i.'- ';
}
while($i<50);
Dans cette configuration, le chiffre 100 est affiché alors que le test logique indique de s'arrêter à 50. Or $i vaut 100 dès le début ...
La question qu'on est en droit de se poser alors est de savoir à quoi cette boucle peut bien servir.
Un exemple est celui d'un frais fixe. L'internaute fait appel à un service de recherches payant, par exemple à 10 euros. Le principe est que la recherche aboutisse ou non, cette dépense est forfaitaire. L'internaute sera facturé de ces 10 euros puis de 15 euros par document fourni.
Essayez de réaliser cet algo. Je vous mets le code en dessous.
On va donc créer un array avec les documents trouvés pour le client. Chaque document est facturé en sus des 10 euros.
$montant = 10; // dès que le client passe commande
$prix = 15; // prix de chaque document
$commande = array('document 1'); // liste des documents trouvés
$i=0; // début de l'itération
do{
if(isset($commande[$i])){
$montant += $prix * ($i+1);
}
$i++;
} while($i<count($commande));
// voilà le montant à payer
echo $montant;
La boucle switch
La boucle permet de "switcher" donc de basculer entre plusieurs possibilités, toutes clairement identifiées. A la fin de cette boucle, une solution standard qui recevra tous les cas non identifiés.
$prenom = "Mathieu";
switch($prenom){
case "Sébastien" :
echo "Bonjour Sébastien";
break;
case "Lubin" :
echo "Bonjour Lubin";
break;
default :
echo "Bonjour";
break;
}
// ou
switch($prenom) :
case "Sébastien" :
echo "Bonjour Sébastien";
break;
case "Lubin" :
echo "Bonjour Lubin";
break;
default :
echo "Bonjour";
break;
endswitch;
Les deux cas identifiés sont celui où le prénom est Sébastien et celui où le prénom est Lubin. Les autres cas seront collectés par le cas "default". Chaque cas se finit par une instruction BREAK qui casse la boucle, qui permet sa sortie.
Exercice
Voici une liste de prénoms. Affichez les tous avec une boucle FOREACH sauf le prénom "sébastien"
$prenoms = array("sébastien", "paul", "hasdin", "fatima", "sébastien", "juliette", "mathieu", "sébastien", "noham","raphaël","dorian")
Corrige
foreach($prenoms AS $p){
if($p != "sébastien){
echo $p.' '; // j'ajoute un espace à la fin pour détacher chaque prénom
}
}
Exercice
Imaginez un club de sport accueillant les jeunes de 6 à 15 ans. Avec l'âge de l'enfant, on pourra déterminer sa catégorie. Réalisez son affection avec une boucle SWITCH.
6 à 10 => poussin
10 à 12 => junior
12 à 15 => senior
$age = 12;
switch($age){
case $age>0 && $age<10 :
echo 'catgéorie poussin';
break;
case $age <= 12 :
echo 'catégorie junior';
break;
case $age <= 15:
echo 'catégorie senior';
break;
default:
echo 'hors catégorie';
break;
}
Exercice
Avec une boucle FOR, écrivez tous les chiffres de 7 à 1589 de 5 en 5, séparés par des tirets. Il ne doit pas y avoir de tiret à la fin.
$dernier = 1589-7+5; // on commence à 7 et on va de 5 en 5
for($i=7; $i<1589; $i+=5){
echo $i;
if($i != $dernier){
echo '- ';
}
}
$i+=5 équivaut à écrire $i = $i+5
Exercice
Je veux créer un dispatcher avec la boucle SWITCH. Le client est et reste sur la page index mais j'appelle à lui les pages qu'il souhaite. Il vous faudra aussi, pour cela, maîtriser les includes en PHP.
<!Doctype html>
<html>
<head>
<title>Dispatcher</title>
<meta name="author" content="Masson Formation">
<meta name="viewport" content="width=device-width;initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="css/style.css">
<meta charset="utf-8">
</head>
<body>
<header>Entête du site</header>
<nav>
<a href="?page=accueil">Accueil</a>
<a href="?page=produits">Produits</a>
<a href="?page=contact">Contact</a>
</nav>
<main>
<?php
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
switch($page){
case 'accueil':
include 'pages/accueil.php';
break;
case 'produits':
include 'pages/produits.php';
break;
case 'contact':
include 'pages/contact.php';
break;
default :
echo 'Désolé cette page ne semble pas exister';
break;
}
?>
</main>
</body>
</html>