Les Boucles

Vous êtes ici : >> PHP / Les Boucles
Temps d'étude : 1h30. Niveau : Moyen.
Tags : Les Boucles
Fichier(s) utile(s) pour ce cours : /

Boucle (structures itératives)

Les boucles (structures itératives) est un moyen de faire répéter une portion de code plusieurs fois.

Nous appelons structure itérative (ou récursive), la structure qui permet d'exécuter plusieurs fois les mêmes instructions. Elle permet d'exécuter "en boucle" un bloc d'instructions.

En 1 mot : Une boucle c'est une répétition !

Comprendre le principe des boucles

Là aussi, il s'agit d'un des chapitres les plus importants de notre apprentissage puisque tous les sites dynamiques du monde incluent forcément un système de boucle à un moment donné.

Contexte : cela sera très utile au moment d'afficher une liste de produits sur un site ecommerce.

Imaginez que le code html suivant permet d'afficher l'un de vos produits :

entrainement.php
	<?php
	
<h2>Tshirt Gris</h2>

30 €


PS : Ce code représente un exemple, il n'est pas à prendre à la lettre pour construire votre page produit ;).

Résultat (exemple) explication PHP


Si vous aviez besoin d'afficher 50 produits par page, pensez-vous que vous copier/collerez votre code html 50 fois ?

NON ! bien entendu ce n'est pas comme cela que ça fonctionne pour plusieurs raisons.

Avec les boucles, nous allons déclarer 1 seule fois le code et le répéter 50 fois automatiquement (50 fois ou autant de fois que ce que l'on souhaite).

Résultat (exemple) explication PHP


Bien entendu, dans la version finale les produits seront différents les uns des autres mais le principe est là.

Vous comprenez le principe et l'intérêt des boucles ?

Nous allons donc voir en pratique avec le code comment nous pourrions enclencher ce phénomène de répétition.

Soyons clair, les boucles c'est un sujet capital, dire "je ne comprends pas" ou "ca ne m'interesse pas, j'attends le concret" revient à dire "je ne programmerais pas de site web dans ma vie".

4 techniques de boucles (répétition) : while, do-while, for, foreach.

La boucle While

entrainement.php
	<?php
	$i = 0; // valeur de départ
	while ($i<5) // tant que $i est inférieur à 5
	{
		echo "$i /"; // affichage
		$i++; // Ceci est une forme contractée de : $i = $i+1; l'incrémentation du "compteur" est effectuée à chaque tour de boucle.
	}

Quelques Explications :

Tour de boucle 0
Ligne 2 : nous déclarons une variable $i et lui affectons la valeur 0
Nous utilisons en général une variable que l'on nomme $i pour INT (interger) mais nous aurions pu la nommer complétement différemment, il n'y a pas d'obligations, juste des usages.

Ligne 3 : While (notre boucle) peut être traduit par "Tant que", ce qui donne tant que $i est inférieur à 5, nous rentrons dans la boucle.
Est-ce que $i est bien inférieur à 5 ? Oui pusique $i est égal à 0. (c'est ce que nous avons déclaré sur la ligne d'au dessus).

Ligne 5 : Nous affichons la valeur contenue dans la variable $i.
Qu'elle est cette valeur ? 0 ! et oui puisque nous avons mis $i = 0; il n'y a pas de raison que cette variable nous donne une autre valeur que 0.
Cela affichera donc "0 /", nous avons mis un slash de séparation mais nous aurions pu choisir un autre caractère.

Ensuite, si nous devons enclencher ce fameux phénomène de répétition (la boucle) il nous faut un système qui puisse compter et progresser dans le nombre de tours que l'on effectuera dans notre boucle.
D'accord pour répéter une portion de code mais combien de fois ? pas à l'infini quand même !

Ligne 6 : Nous utilisons $i++; (forme contractée de $i = $i + 1) afin de rendre cette variable évolutive.
$i est la variable qui permettra d'entrer dans la boucle afin d'effectuer des tours.
C'est à dire que lorsque cette ligne s'exécutera, $i passera de 0 à 1. puis ensuite de 1 à 2. et ainsi de suite...

Au moment où la ligne 6 nous permet d'incrémenter notre variable $i, l'interpréteur remonte automatiquement (dans le cas d'une boucle comme ici) sur la ligne 3 pour tenter d'exécuter à nouveau son contenu.

Ca veut dire que nous remontons dans le code et revenons sur la ligne n°3 !

Tour de boucle 1
Ligne 3 : Par conséquent, l'interpréteur test à nouveau la condition d'entrée dans la boucle : est-ce que $i est bien inférieur à 5 ?
Oui, encore 1 fois ! puisque cette fois-ci $i est passé à 1 (grâce au $i++; vu précedemment).
1 est bien inférieur a 5, nous rentrons à nouveau dans la boucle while.

Ligne 5 : Nous affichons à nouveau la valeur contenue dans la variable $i.
Cela affichera "1 /".

Ligne 6 : Nous repassons sur la ligne $i++; (forme contractée de $i = $i + 1) afin de passer $i à 2.
L'interpréteur remonte à nouveau dans le code (ligne 3 précisément) et nous observons à nouveau le cycle suivant :

Tour de boucle 2
Ligne 3 : la condition d'entrée renvoie TRUE (vrai) et nous entrons à nouveau dans la boucle while (puisque $i 2 < 5).
Ligne 5 : Nous affichons "2 /" (instruction d'affichage echo).
Ligne 6 : Nous incrémentons $i à 3 (2+1)

Tour de boucle 3
Ligne 3 : la condition d'entrée renvoie TRUE (vrai) et nous entrons à nouveau dans la boucle while (puisque $i 3 < 5).
Ligne 5 : Nous affichons "3 /" (instruction d'affichage echo).
Ligne 6 : Nous incrémentons $i à 4 (3+1)

Tour de boucle 4
Ligne 3 : la condition d'entrée renvoie TRUE (vrai) et nous entrons à nouveau dans la boucle while (puisque $i 4 < 5).
Ligne 5 : Nous affichons "4 /" (instruction d'affichage echo).
Ligne 6 : Nous incrémentons $i à 5 (3+1)

Ensuite l'interpréteur tente de retourner ligne 3 pour exécuter à nouveau la boucle mais ça n'est pas possible dans la mesure où $i est passé à 5 et 5 n'est pas inférieur à 5.

Résultat Final

0 / 1 / 2 / 3 / 4


De 0 à 4, ça fais bien 5 tours au total !

Reprenons les explications une à une :

 $i = 0; 
C'est ce qui représente notre valeur de départ.


 while 
Nous pouvons remplacer "while" par "tant que".


($i<5) 
C'est ce qui représente notre condition d'entrée dans la boucle ($i doit forcément être inférieur à 5 pour que l'on puisse rentrer).
Nous avons mis 5 pour réaliser 5 tours mais nous aurions pu mettre 10, 20, 100 ou le nombre que vous souhaitez.


 while($i<5) 
Traduction : Tant que $i est inférieur à 5 nous rentrons dans la boucle.
Notre condition d'entrée c'est ce qui permet de ne pas avoir une boucle infinie et de pouvoir s'arreter à un moment donné (après 5 tours).


 { } 
Les accolades permettent de fixer le périmètre de la boucle


 echo "$i /"; 
Affiche le chiffre contenu dans la variable $i suivi d'un slash "/"


 $i++; 
$i est incrémenté (indispensable pour faire tourner la boucle), c'est l'équivalent de $i = $i + 1; et nous en avons besoin pour enclencher "le tour suivant" à chaque fois.


	<?php
	$i = 0;
	while ($i<5)
	{
		echo "$i /";
		$i++;
	}
Ce cycle est repétée 5 fois (5 tours de boucle).


explication PHP

La boucle DoWhile

Concernant la boucle do-while, il s'agit exactement du même principe que la boucle while, la seule différence réside dans le fait que la condition d'entrée est testée à la fin plutôt qu'au début.

On entre d'abord et ensuite on vérifie si l'on peux continuer à boucler.

entrainement.php
	$i = 0;
	do {
		echo $i;
	} while ($i > 0);

Cette boucle ne fera qu'un seul tour car $i n'est pas supérieur à 0.

Nous l'utiliserons plus rarement, plutôt dans des cas spécifique.

Vous pouvez la garder à l'esprit pour savoir qu'elle existe si on vous en parle ou que vous la croisez dans un code mais vous n'êtes pas obligé de la connaitre par coeur.

La boucle For

Tout comme la boucle while, l'objectif de cette boucle est aussi d'effectuer une répétition de code.
La structure est légérement différente au niveau de la syntaxe :

entrainement.php
	for($j = 0; $j <= 15; $j++)
	{
		echo $j;
	}
Quelques Explications :

for($j = 0; $j <= 15; $j++)
Voici à quoi correspond notre boucle :

$j= 0; - Valeur de départ c'est l'initialisation qui indique la variable qui servira de compteur ainsi que sa valeur initiale.
$j <= 15; - Condition d'entrée condition pour continuer les boucles. L'instruction s'achève dès que la condition renvoie faux.
$j++ - Evolution : évolution du compteur à chaque tour de boucle (généralement une incrémentation ou décrémentation).


echo $j;
L'instruction echo permet d'afficher la valeur contenue dans la variable $j.

Résultat

0123456789101112131415


La boucle fait 16 tours au total, de 0 à 15.

Exercice : serait-il possible de passer les nombres à la ligne les uns à la suite des autres ?

Voici le résultat attendu :

Résultat

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15


A vous de jouer ! et ne regardez pas la correction en dessous avant d'y être parvenu, ça vous entrainera !

Correction :
entrainement.php
	for($j = 0; $j <= 15; $j++)
	{
		echo "

$j

"; }
Il suffisait de mettre un <br> ou de faire appel aux balises <p> </p> pour faire succéder à la ligne les différents chiffres écrits par notre boucle.

En effet, avec l'écriture des balise <p> </p> ou <br> une seule fois, cela se répétera autant de fois que demandé puisque nous sommes dans les accolades de la boucle et donc dans l'effet de répétition.

Pensez à regarder le code-source généré ! Ctrl+U ou clic droit -> code source de la page

Autre exercice, maintenant que vous avez vu que l'on pouvait mélanger du code php et html dans le cadre des boucles, pourriez vous proposer un champ date de naissance en prévoyant les 31 jours existants dans notre calendrier :

Voici le résultat attendu :

Résultat attendu Quel est votre jour de naissance ?

L'exercice est donc de parvenir à ce résultat sans faire de copier/coller. A vous de jouer !

Pour vous aider (si vous aviez un doute sur le code html), voici les lignes permettant d'obtenir une liste de choix déroulante :

entrainement.php
	
	

L'objectif est donc d'avoir 1 seul select et 31 options (sans les écrire manuellement, sinon je vous en demande 10 000, on verra si vous faites toujours des copiers/coller =D).

Voici la correction :

entrainement.php
	echo '';
Nous voulions qu'1 seul <select> mais 31 options, c'est la raison pour laquelle le select se trouve en dehors des accolades de la boucle (nous ne souhaitons pas qu'il soit répété), les options se trouvent dans les accolades de notre boucle (pour qu'elles bénéficient de l'effet de répétition).

Nous commençons la boucle a 1, car personne est né le 0 ! nous nous arretons a 31 (car personne est né le 32).
Il y aura donc 31 tours et 31 options.

Nous aurions pu créer cette boucle dans l'autre sens ( de 31 à 1 et non de 1 à 31 ), on parle alors de décrémentation :
entrainement.php
	echo '';

Nous commençons notre compteur ($j) à 31,
Tant que nous sommes supérieur ou égal à 1 nous rentrons dans la boucle
$j-- permet de baisser le nombre à chaque tour afin de faire progresser la boucle

Résultat attendu Quel est votre jour de naissance ?

La boucle Foreach

La boucle foreach sera vue dans le chapitre dédié aux arrays.
(Elle permet d'afficher les valeurs d'un tableau de données array).

Choix : boucle while / for / foreach / dowhile

Dans tous les cas, l'objectif d'une boucle est de répéter une portion de code.

Selon la situation, il peut être plus aisé d'utiliser la structure de l'une d'entre elles.

Nous y reviendrons plus tard dans le cours et à force de les utiliser, nous serons quelle structure est la plus adaptée dans les différents cas.

Boucle imbriquée (Double boucle)

Voici une boucle permettant d'afficher des données dans une table (tableau) html

entrainement.php
	echo "<table border=\"1\"><tr>";
	for($i = 0; $i < 9; $i++)
	{
		echo "<td>  $i  </td>";
	}
	echo "</tr></table>";
Résultat
0 1 2 3 4 5 6 7 8

Exercice : essayez de reproduire ces données :

Résultat attendu
0123456789
10111213141516171819
20212223242526272829
30313233343536373839
40414243444546474849
50515253545556575859
60616263646566676869
70717273747576777879
80818283848586878889
90919293949596979899

Voici la correction possible :

entrainement.php
	echo '<table border="1">';
	for($ligne = 0; $ligne < 10; $ligne++) //ligne est à zéro
	{
		echo '<tr>';
		for($cellule = 0; $cellule < 10; $cellule++) // tant que ligne est à  zéro, cellule s'incrémente 10 fois - ligne est à 1, cellule s'incrémente 10 fois - ligne est à 2, cellule s'incrémente 10 fois, etc...
		{
			echo '<td>' . (10 * $ligne + $cellule) . '</td>'; // 10 * 0 +0 ,  10* 0 + 1, 10* 0 + 2, etc... --- 10* 1+0, 10* 1 + 1, 10* 1+2, etc. Permet d'avoir les multiples de 10.
		}
		echo '</tr>';
	} 
	echo '</table>';

Quelques Explications :

Tour de boucle $ligne 0, $cellule 0 :

$ligne est à 0. (<10) nous rentrons dans la première boucle.
Nous faisons le 1er <tr>

$cellule est à 0 (<10) nous rentrons dans la deuxième boucle.
Nous faisons le 1er <td> avec le calcul suivant 10*$ligne+$cellule, ce qui donne 10*0+0 = 0.
0



Tour de boucle $ligne 0, $cellule 1 :

$ligne reste à 0.
Très important pour la compréhension : nous ne rerentrons pas dans la première boucle mais restons "coincé" dans la deuxième (le temps que ses tours soient terminés).

$cellule passe à 1 (<10) nous rentrons à nouveau dans la deuxième boucle.
Nous faisons le 2ème <td> avec le calcul suivant 10*$ligne+$cellule, ce qui donne 10*0+1 = 1.
01



Tour de boucle $ligne 0, $cellule 2 :

$ligne reste à 0.
Nous ne rentrons pas dans la première boucle mais restons toujours "coincé" dans la deuxième (le temps que ses tours soient terminés).

$cellule passe à 2 (<10) nous rentrons à nouveau dans la deuxième boucle.
Nous faisons le 3ème <td> avec le calcul suivant 10*$ligne+$cellule, ce qui donne 10*0+2 = 2.
012



Et ainsi de suite jusqu'à ce que $cellule atteigne 10.
012345678910


C'est là que tout se joue.
Nous rentrons à nouveau dans la 1ère boucle et $ligne passe à 1.
$cellule est quant à elle remise à 0 puisque nous repassons dans les lignes qui initialisent la variable.


Tour de boucle $ligne 1, $cellule 0 :

$ligne est à 1. (<10) nous rentrons dans la première boucle.
Nous faisons le 2ème <tr> (ce qui a pour effet de passer à la ligne)

$cellule est à 0 (<10) nous rentrons dans la deuxième boucle.
Nous faisons le 1er <td> de cette nouvelle ligne (et 11e au total, puisqu'il s'agit du 11e tour) avec le calcul suivant 10*$ligne+$cellule, ce qui donne 10*1+0 = 11.
012345678910
11



Tour de boucle $ligne 1, $cellule 1 :

$ligne reste à 1.(<10)
nous ne rerentrons pas dans la première boucle mais restons "coincé" dans la deuxième (le temps que ses tours soient terminés).

$cellule passe à 1 (<10) nous rentrons à nouveau dans la deuxième boucle.

Nous faisons le 2ème <td> de cette nouvelle ligne avec le calcul suivant 10*$ligne+$cellule, ce qui donne 10*1+1 = 12.
012345678910
1112



Tour de boucle $ligne 1, $cellule 2 :

$ligne reste à 1. (<10)
Nous ne rerentrons pas dans la première boucle mais restons "coincé" dans la deuxième (le temps que ses tours soient terminés).

$cellule passe à 2 (<10)
Nous rentrons à nouveau dans la deuxième boucle.

Nous faisons le 3ème <td> de cette nouvelle ligne avec le calcul suivant 10*$ligne+$cellule, ce qui donne 10*1+2 = 13.
012345678910
111213



Et ainsi de suite... voici les tours de boucles précis :
$ligne 0 , $cellule 0$ligne 0 , $cellule 1$ligne 0 , $cellule 2$ligne 0 , $cellule 3$ligne 0 , $cellule 4$ligne 0 , $cellule 5$ligne 0 , $cellule 6$ligne 0 , $cellule 7$ligne 0 , $cellule 8$ligne 0 , $cellule 9
$ligne 1 , $cellule 0$ligne 1 , $cellule 1$ligne 1 , $cellule 2$ligne 1 , $cellule 3$ligne 1 , $cellule 4$ligne 1 , $cellule 5$ligne 1 , $cellule 6$ligne 1 , $cellule 7$ligne 1 , $cellule 8$ligne 1 , $cellule 9
$ligne 2 , $cellule 0$ligne 2 , $cellule 1$ligne 2 , $cellule 2$ligne 2 , $cellule 3$ligne 2 , $cellule 4$ligne 2 , $cellule 5$ligne 2 , $cellule 6$ligne 2 , $cellule 7$ligne 2 , $cellule 8$ligne 2 , $cellule 9
$ligne 3 , $cellule 0$ligne 3 , $cellule 1$ligne 3 , $cellule 2$ligne 3 , $cellule 3$ligne 3 , $cellule 4$ligne 3 , $cellule 5$ligne 3 , $cellule 6$ligne 3 , $cellule 7$ligne 3 , $cellule 8$ligne 3 , $cellule 9
$ligne 4 , $cellule 0$ligne 4 , $cellule 1$ligne 4 , $cellule 2$ligne 4 , $cellule 3$ligne 4 , $cellule 4$ligne 4 , $cellule 5$ligne 4 , $cellule 6$ligne 4 , $cellule 7$ligne 4 , $cellule 8$ligne 4 , $cellule 9
$ligne 5 , $cellule 0$ligne 5 , $cellule 1$ligne 5 , $cellule 2$ligne 5 , $cellule 3$ligne 5 , $cellule 4$ligne 5 , $cellule 5$ligne 5 , $cellule 6$ligne 5 , $cellule 7$ligne 5 , $cellule 8$ligne 5 , $cellule 9
$ligne 6 , $cellule 0$ligne 6 , $cellule 1$ligne 6 , $cellule 2$ligne 6 , $cellule 3$ligne 6 , $cellule 4$ligne 6 , $cellule 5$ligne 6 , $cellule 6$ligne 6 , $cellule 7$ligne 6 , $cellule 8$ligne 6 , $cellule 9
$ligne 7 , $cellule 0$ligne 7 , $cellule 1$ligne 7 , $cellule 2$ligne 7 , $cellule 3$ligne 7 , $cellule 4$ligne 7 , $cellule 5$ligne 7 , $cellule 6$ligne 7 , $cellule 7$ligne 7 , $cellule 8$ligne 7 , $cellule 9
$ligne 8 , $cellule 0$ligne 8 , $cellule 1$ligne 8 , $cellule 2$ligne 8 , $cellule 3$ligne 8 , $cellule 4$ligne 8 , $cellule 5$ligne 8 , $cellule 6$ligne 8 , $cellule 7$ligne 8 , $cellule 8$ligne 8 , $cellule 9
$ligne 9 , $cellule 0$ligne 9 , $cellule 1$ligne 9 , $cellule 2$ligne 9 , $cellule 3$ligne 9 , $cellule 4$ligne 9 , $cellule 5$ligne 9 , $cellule 6$ligne 9 , $cellule 7$ligne 9 , $cellule 8$ligne 9 , $cellule 9

En conclusion, lorsque nous faisons un tour dans la boucle avec $ligne, cela en entraine 10 dans la boucle avec $cellule.
Au total la première boucle (avec $ligne) tourne 10 fois et la deuxième boucle (avec $cellule) tourne 100 fois.

Voici une autre correction possible :
entrainement.php
	$z = 0;
	echo '<table border="1">';
	for($ligne = 0; $ligne < 10; $ligne++) //ligne est à zéro
	{
		echo '<tr>';
		for($cellule = 0; $cellule < 10; $cellule++)
		{
			echo '<td>' . $z . '</td>';
			$z++;
		}
		echo '</tr>';
	}
	echo '</table>';
Solution avec une seule boucle PHP et l'utilisation du modulo (code html non valide) :
entrainement.php
	echo '<table border="1"><tr>';
	for($i = 0; $i < 100; $i++) //ligne est à zéro
	{
		if($i % 10 == 0)
		{
			echo '</tr>';
		}
		echo '<td>' . $i . '</td>';
	}
	echo '</table>';
	
Solution différente :
entrainement.php
	echo '<table border="1">';
	$i = 0;
	while($i <= 99)
	{	
		echo '<tr>';
		for($k = 0; $k <= 9 ; $k++)
		{
			echo "<td>$i</td>";
			$i++;
		}
		echo '</tr>';
	}
	echo '</table>';