Structures avancées en PHP

Un programme en PHP est constitué d'une suite d'instructions ayant pour but de répondre à / résoudre une problèmatique posée. Cette problématique peut nécessité une adaptation aux conditions de réalisation et/ou une répétition d'une partie des instructions.

Adaptation par les tests conditionnels

Un test conditionnel permet de vérifier une assertion et en fonction de sa "valeur", activer une réponse ou une autre.

Si...

Le test conditionnel "si" est le plus utilisé. En algorithmique, cela s'écrit ainsi :

si il fait froid alors
    je prends mon pull
sinon
    je ne prends pas mon pull
finsi

Une simplification d'écriture serait :

si il fait froid alors
    je prends mon pull
finsi

Retranscrit en PHP avec une variable "temperature" contenant la température actuelle :

if ($temperature < 20) {
    echo 'je prends mon pull';
} else {
    echo 'je ne prends pas mon pull';
}
Des parenthèses entourent toujours entièrement la condition

Et sa rédaction simplifiée :

if ($temperature < 20)
    echo 'je prends mon pull';

Exercice n°12

Dans une page PHP

  1. créez un bloc PHP
  2. définissez une variable "pluie" et affectez lui la valeur true
  3. s'il pleut ça affiche "prendre son parapluie" sinon "laisser le parapluie"
  4. modifiez la valeur de la variable "pluie" en false

Les accolades permettent de délimiter un bloc d'instructions qui sont conditionnées de celles qui ne le sont pas.

si il fait froid alors
    je prends mon pull
    je prends mon écharpe
sinon
    je ne prends pas mon pull
    je ne prends pas mon écharpe
finsi
je vais en ville

Retranscrit en PHP :

if ($temperature < 15) {
    echo 'je prends mon pull';
    echo 'je prends mon écharpe';
} else {
    echo 'je ne prends pas mon pull';
    echo 'je ne prends pas mon écharpe';
}
echo 'je vais en ville';

avec le retour à la ligne pour la lisibilité des blocs :

if ($temperature < 15)
{
    echo 'je prends mon pull';      // 
    echo 'je prends mon écharpe';   // 
} else
{
    echo 'je ne prends pas mon pull';       // 
    echo 'je ne prends pas mon écharpe';    // 
}
echo 'je vais en ville';    //  

Exercice n°13

Dans une page PHP

  1. créez un bloc PHP
  2. définissez une variable "pluie" et affectez lui la valeur true
  3. écrivez un test conditionnel tel que
    • s'il pleut ça affiche "prendre son parapluie" sinon "laisser le parapluie"
    • placez les accolades pour chacun des blocs d'instructions
    • ajoutez dans le bloc "vrai" une instruction pour afficher "prendre une veste"
    • ajoutez dans le bloc "faux" une instruction pour afficher "prendre un gilet"
  4. ajoutez une instruction en dehors du test affichant "prendre sa carte de bus"
  5. retirer les accolades du bloc "faux" uniquement ; observez ce qui s'affiche
  6. modifiez la valeur de pluie à false ; observez ce qui s'affiche

Certaines fois, les cas possibles sont multiples et dès lors, les tests sont multiples également. Si on veut, par exemple, afficher la capitale d'un pays en fonction du pays :

$capitale;
if ($pays == 'France') {
    $capitale = 'Paris';
	echo 'La capitale est Paris';
}
if ($pays == 'Italie') {
    $capitale = 'Rome';
	echo 'La capitale est Rome';
}
if ($pays == 'Belgique') {
    $capitale = 'Bruxelle';
	echo 'La capitale est Bruxelle';
}
if ($pays == 'Espagne') {
    $capitale = 'Madrid';
    echo 'La capitale est Madrid';
}
echo 'Vous avez trouvé la capitale : '.$capitale;

Mais ce bout de programme, bien que conforme, n'est pas optimisé car il réalise plusieurs instructions qui ne sont pas nécessaires. Une optimisation serait que lorsque le programme a trouvé la capitale il ne réalise pas les tests suivants et pour cela il faut utiliser le mot clé else (= sinon en français) et imbriquer les conditions :

if ($pays == 'France') {
	echo 'La capitales est Paris';
} else {
	if ($pays == 'Italie') {
		echo 'La capitales est Rome';
	}
}
Pour n'en oublier aucune, il faut fermer de suite une accolade qu'on vient d'ouvrir.

Exercice n°14

Dans une page PHP

  1. créez un bloc PHP
  2. reprenez le début de bloc conditionnel sur la France et l'Italie
  3. ajoutez le cas de la Belgique de manière à ce qu'il soit testé dans le "sinon" de l'Italie
  4. ajoutez le cas de l'Espagne de manière à ce qu'il soit testé dans le "sinon" de la Belgique
  5. définissez la variable pays et testez pour chaque valeur de pays possible

PHP permet encore de simplifier cela en utilisant le mot clé elseif (=sinon si en français) :

if ($pays == 'France') {
	echo 'La capitales est Paris';
} elseif ($pays == 'Italie') {
	echo 'La capitales est Rome';
}

Exercice n°15

Dans une page PHP

  1. créez un bloc PHP
  2. dupliquez le bloc de tests précédent et ajoutez le dans ce bloc
  3. simplifiez son écriture en utilisant le mot clé elseif
  4. testez pour chaque valeur de pays possible

Les tests n'impliquant qu'une valeur sont relativement simples à mettre en place.

Exercice n°16

Dans une page PHP

  1. créez un bloc PHP
  2. rédigez les tests conditionnels de l'exercice suivant :
    1. Les places pour un concert sont vendues à une personnes avec un maximum de 5 places par transaction :
      • le prix d'une place seule est à 25 euros
      • si 2 places sont prises, le prix de la place est de 23,50 euros
      • si 3 places sont prises, le prix est de 21,50 euros
      • si 4 places sont prises, le prix est de 20 euros
      • si 5 places sont prises, le prix est de 19 euros
  3. définissez une variable contenant le nombre de place, affectez 3 comme valeur
  4. définissez une variable contenant le prix à la place
  5. affichez le montant total que la personne devra régler
  6. modifiez la valeur de la variable stockant le nombre de places : 0, 5, 10

Dans d'autres cas encore, le test à réaliser est double, comme lorsque l'on souhaite vérifier si une valeur est comprise entre deux autres valeurs : en effet, en programmation classique, il n'est pas possible d'écrire ça en un unique test (10 <= $x < 100) mais en deux tests liés par un opérateur booléen ($x >= 10 && $x < 100).

if ($x > 0 && $x < 100) {
    echo 'x est compris entre 0 et 100';
} else {
    echo 'x est négatif ou supérieur ou égale à 100';
}

Exercice n°17

Dans une page PHP

  1. créez un bloc PHP
  2. rédigez les tests conditionnels de l'exercice suivant :
    1. Une boutique en ligne a défini le coût des frais de port ainsi : :
      • si le montant de la commande est inférieur ou égal à 15 euros, le coût est de 3 euros
      • si il est supérieur à 15 et inférieur ou égal à 25 euros, les frais de port sont à 2,50 euros
      • si il est supérieur 25 et inférieur ou égal à 35 euros, les frais de port sont à 2 euros
      • au-delà de 35 euros, ils sont offerts
    2. La boutique souhaite remercier les clients ayant un montant de commande égal ou supérieur à 26 en leur envoyant en plus un bon d'achat en cadeau. Compléter les tests précédents en insérant si nécessaire l'instruction : $va_recevoir_cadeau = true;
$pluvieux == true est équivalent à $pluvieux
$pluvieux == false est équivalent à !$pluvieux

Dans le cas où...

Le test conditionnel "dans le cas où..." permet de tester une assertion par rapport à plusieurs autres.
C'est un test mis en place quand la valeur à tester est simple et que les cas possibles sont nombreux.
Un tel test mis en place en utilisant le test de conditionnel "si" est possible mais les imbrications de si rendraient l'écriture complexe et la lecture d'un tel code moins facilement compréhensible.
Sa syntaxe est la suivante :

SELON (pays) FAIRE
    Cas "France" : ECRIRE("La capitale est Paris")
    Cas "Italie" : ECRIRE("La capitale est Rome")
    Cas "Belgique" : ECRIRE("La capitale est Bruxelle")
    Cas "Espagne" : ECRIRE("La capitale est Madrid")
    SINON : ECRIRE("Ce pays n'est pas reconnu")
FINSELON
            

Retranscrit en PHP avec le mot clé switch :

switch ($pays) {
    case 'France' : echo 'La capitale est Paris'; break;
    case 'Italie' : echo 'La capitale est Rome'; break;
    case 'Belgique' : echo 'La capitale est Bruxelle'; break;
    case 'Espagne' : echo 'La capitale est Madrid'; break;
    default: echo 'Ce pays n'est pas reconnu';
}

La syntaxe nécessite la présence des mots clés :

  • switch, suivi de la variable à tester entre parenthèses
  • case suivi de l'une des valeurs possibles, suivi d'un double points marquant le début des instructions
  • break qui marque la fin de la série d'instructions
  • default qui va indiquer le cas si aucun autre ne correspond, suivi d'un double point

Le mot clé break est particulier : il est obligatoire sous peine de voir les instructions des cas suivants le cas valide d'être réalisées.

switch ($ville) {
    case 'Paris' :
        $habitant = 'Parisien';
        $transport = 'métro ou bus';
        break;
    case 'Nancy' :
        $habitant = 'Nancéen';
        $transport = 'tram ou bus';
        break;
    case 'Metz' :
        $habitant = 'Messins';
        $transport = 'Mettis ou bus';
        break;
    default :
        $habitant = 'habitant de ville inconnue';
        $transport = 'marche à pieds au minimum';
}

Exercice n°18

Dans une page PHP

  1. créez un bloc PHP
  2. rédigez les tests conditionnels "Dans le cas où.." de l'exercice suivant :
    1. Les places pour un concert sont vendues à une personnes avec un maximum de 5 places par transaction :
      • le prix d'une place seule est à 25 euros
      • si 2 places sont prises, le prix de la place est de 23,50 euros
      • si 3 places sont prises, le prix est de 21,50 euros
      • si 4 places sont prises, le prix est de 20 euros
      • si 5 places sont prises, le prix est de 19 euros
  3. définissez une variable contenant le nombre de place, affectez 3 comme valeur
  4. définissez une variable contenant le prix à la place
  5. affichez le montant total que la personne devra régler
  6. modifiez la valeur de la variable stockant le nombre de places : 0, 5, 10

Parfois omettre le mot clé break peut permettre de prendre en compte plusieurs cas possibles pour lesquels les instructions seraient les mêmes :

switch ($nombre_enfant) {
    case 0 :
        $famile = 'sans enfant'; break;
    case 1 :
    case 2 :
        $famile = 'petite'; break;
    case 3 :
    case 4 :
        $famile = 'grande'; break;
    case 5 :
    case 6 :
        $famile = 'très grande'; break;
    default :
        $famile = 'conséquente;
}

Dans cet exemple, si une famile a un seul enfant, le cas 1 étant valide mais n'ayant pas de break, ce sont les instructions du cas 1 (absente dans notre exemple) et du cas 2 qui seront réalisées. Comme le cas 2 dispose de l'instruction break, l'instruction suivante réalisée sera celle située après l'accolade du switch.

Opérateur ternaire

L'opérateur ternaire est une simplification d'écriture permettant en une ligne d'affecter une valeur à une variable en fonction du résultat d'un test.

variable = (condition)? valeur_si_vrai : valeur_si_faux;

Par exemple :

$prix_frais_port = ($montant_commande > 50)? 0 : 3.50;

Si le montant de la commande est supérieur à 50 euros, les frais de port sont offerts sinon, ils sont à 3,50 euros.

Type tableau

Le type tableau appartient à la catégorie "type composé".
Les tableaux sont des structures qui permettent d’organiser des variables d'un même type (normalement) et sous un même thème : on parle d’ensemble de variables. L’intérêt est que l’ensemble des variables est centralisé sous un nom.

Un tableau est défini par le nom du tableau suivi d’un crochet ouvrant et d’un crochet fermant :

$nom_du_tableau[];

Le nom d'un tableau respecte les mêmes règles de nommage vues pour les variables.

Certaines conventions recommandent de distinguer le type tableau d'une variable simple dans son nom

Ainsi le nom pourra être au pluriel ou précédé d'une lettre t ou a; par exemple, pour un tableau contenant les saisons :

  • $saisons;
  • ou $tSaison; //t pour tableau & la notation polonaise avec le S majuscule
  • $t_saison;

Initialisation de tableau

Les éléments d’un tableau sont structurés sous la forme d’une paire « clé / valeur » où la clé (ou indice de tableau) définit l’emplacement dans le tableau de la valeur :

nom_du_tableau[la_clef]  la_valeur_associée_à_la_clef

Par exemple en PHP :

$departements[57] = 'Moselle';

La définition (ou initialisation) d'un tableau sans valeur se fait de plusieurs manières :

$t_cours = array();     // ancienne écriture (avant PHP 7.0)
$t_cours = [];  //nouvelle écriture, préférée à l'ancienne

La définition d'un tableau avec valeur se fait également de plusieurs manières :

$t_cours = ['HTML5 / CSS3'];    // ou
$t_cours[] = 'HTML5 / CSS3';    // ou
$t_cours[3] = 'HTML5 / CSS3';

La première instruction offre l'avantage d'initialiser un tableau avec une ou plusieurs valeurs :

$t_cours = ['HTML5 / CSS3', 'jQuery', 'Javascript'];
L'initialisation est une étape qui crée le tableau ou le reset s'il existe déjà

Par défaut, si aucun indice n'est définit, celui-ci est de type numérique et commence à 0.
Dans le cas de l'initialisation avec valeur :

$t_cours = ['HTML5 / CSS3'];
$t_cours[] = 'HTML5 / CSS3'; //avec le tableau qui n'existe pas avant l'instruction

les deux instructions correspondent à :

$t_cours[0] = 'HTML5 / CSS3';

Quant à :

$t_cours[3] = 'HTML5 / CSS3';

cela revient à placer la valeur à conserver dans le 4ème emplacement.

Par défaut, la première position dans un tableau est à l'indice 0

Si nous voulons compléter le tableau, il est possible de compléter des éléments manquants :

$t_cours[0] = 'PHP';
$t_cours[1] = 'Javascript';
$t_cours[2] = 'jQuery';

ou PHP peut gérer lui-même les indices et donc l'instructions suivante :

$t_cours = ['HTML5 / CSS3', 'jQuery', 'Javascript'];

revient à mettre 'HTML5 / CSS3' à l'indice 0, 'jQuery' à l'indice 1, 'Javascript' à l'indice 2.

Une autre simplification offerte par PHP est qu'il complète lui même les indices numériques à partir du dernier renseigné. Si je ne renseigne pas l'indice à l'initialisation, ça partira de 0 et le suivant sera enregistré à la position de l'indice 1. Si je renseigne l'indice de départ, le prochain ajout se fera à l'indice choisit +1.
Pour cela, il suffit de laisser les crochets vides lors d'une affectation :

$t_cours = [];
$t_cours[3] = 'HTML5 / CSS3';
$t_cours[] = 'Node.js';     //placé à l'indice 4

Pour accéder à la valeur correspondante à une clé (indice), il suffit d'écrire :

echo $t_cours[3];
Demander l'affichage d'un tableau en omettant d'indiquer un indice entrainera une erreur PHP

Le type tableau étant un type complexe, il n'est pas possible d'utiliser echo pour en afficher le contenu. Par contre, dans un but de débugage, il est possible d'utiliser la fonction print_r(nom_du_tableau)

echo $t_cours;      //-> ERREUR !
print_r($t_cours);      //-> pour vérifier son tableau

Une autre fonction utile est la fonction count(nom_du_tableau) qui retourne le nombre d'élément dans un tableau.

echo count($t_cours);      // affichera 3 si le tableau contient 3 éléments

Il est aussi possible de faire une copie de variable entre un indice d'un tableau et une variable (et inversement) :

$valeur = $t_cours[3];

Exercice n°19

Dans une page PHP

  1. créez un bloc PHP
    • déclarez un tableau vide avec un nom valide
    • affectez lui deux valeurs sans préciser les indices
    • créez un tableau $t_semaine_1 en l'initialisant avec les jours de la semaine (lundi, mardi, etc.)
    • affichez le contenu de ce tableau à l'indice 3
    • réalisez une concaténation entre "le jour à l'indice 2 est" et la valeur à l'indice 2
    • créer un autre tableau $t_semaine_2 pour les jours de la semaine allant de dimanche à lundi
    • afficher le contenu de ce tableau à l'indice 3
    • créer le tableau $t_semaine_3 en plaçant lundi à l'indice 6
    • ajoutez les autres jours sans préciser l'indice
    • affichez le contenu à l'indice 9

Tableau associatif

En plus des indices de type entier numérique, il est possible d'indexer un tableau avec une chaîne de caractères. Ce type de tableau est appelé tableau associatif.
Cela fonctionne de la même manière qu'avec un indice numérique :

$t_saison = [];    //ou
$t_saison['automne'] = 'octobre, novembre, décembre';
echo $t_saison['automne'];

Néanmoins, à contrario des indices numériques de type entier, PHP ne peut prévoir l'indice suivant d'un tableau associatif et ajoutera le(s) prochain(s) élément(s) à partir de 0 si aucun indice n'est défini.

$t_test['aab'] = 'jus';
$t_test[] = 'pomme';    //à l'indice 0
$t_test['aac'] = 'jus';
$t_test[] = 'poire';    //à l'indice 1
Par convention, il faut éviter de définir un tableau comprenant indexage numérique et indexage associatif.

Exercice n°20

Dans une page PHP

  1. créez un bloc PHP
  2. déclarer un tableau $t_prenom
  3. ajouter une paire (prenom_A, "Anne Anabelle Amélie")
  4. ajouter une paire (prenom_P, "Paul Pierre Patrick")
  5. ajouter une paire (prenom_S, "Sophie Sylvie Stéphanie")
  6. faites un affichage des 3 valeurs du tableau

NB : paire = (indice, valeur)

Tableau multidimensionnel

Il est également possible d'ajouter un tableau à l'indice d'un autre tableau, créant ainsi un tableau portant sur 2 dimensions.

$t_saison = [];
$t_saison['printemps'] = ['avril', 'mai', 'juin'];
$t_saison['été'] = ['juillet', 'août', 'septembre'];
$t_saison['automne'] = ['octobre', 'novembre', 'décembre'];
$t_saison['hiver'] = ['janvier', 'février', 'mars'];

Pour lire un contenu précis, il faut connaître sa position dans le tableau. Par exemple, le 2ème mois de l'été :

echo $t_saison['été'][1];
Dans un tel tableau, il faut que chaque dimension ait un type d'indice (numérique ou chaîne de caractères) et non les deux en même temps.

Exercice n°21

Dans une page PHP

  1. créez un bloc PHP
  2. recréez le tableau $t_prenom de l'exercice précédent en tableau à 2 dimensions
  3. affichez les prénoms suivants en les retrouvant dans le tableau
    • Paul
    • Amélie
    • Sophie

D'une page à l'autre

Il existe plusieurs méthodes permettant de transmettre (ou conserver) une information d'une page à l'autre.

Méthode GET

C'est la méthode la plus simple mais qui est limitée en nombre de caractère étant donné que l'URL ne peut avoir que 255 caractères de long.
Pour l'utiliser, il suffit de placer dans le lien des ensembles de couples nom/valeur, séparés entre eux par le caractère & et séparés de l'adresse de la page par le point d'intérogation :

<a href="vers_ma_page.php?param_1=valeur_1&param_2=valeur_2">continuer</a>

Les caractères spéciaux et les espaces doivent être encodés pour éviter des bugs. La fonction urlencode() et son inverse urldecode() sont utiles à ces fins.

$param_1 = urlencode('c\'est l\'été');

La récupération du contenu sur la page du lien se fait en utilisant la super variable $_GET qui est un tableau de type associatif mis à disposition par le serveur PHP. Le nom, du couple nom/valeur, est alors l'indice dans ce tableau.

echo $_GET['param_1'];

La méthode Get peut aussi être utilisée pour l'envoi en traitement d'un formulaire si les données transmises ne sont pas sensibles.

Exercice n°22

  1. créez une page PHP nommée depart.php et une page arrivee.php
  2. dans la page depart.php, créez un lien vers la page arrivee.php
  3. ajoutez un paramètre à transmettre nommé test avec la valeur 123
  4. récupérez et affichez la valeur au niveau de la page arrivee.php
  5. ajoutez 3 autres paramètres

Méthode POST

Etroitement liée au formulaire, la méthode Post est la méthode utilisée lors de traitement de formulaire.
Pour l'utiliser, il suffit de définir que la méthode d'envoi du formulaire est réalisée via cette méthode.

<form action="une_page.php" method="post">

La récupération du contenu sur la page inscrite dans l'attribut action de la balise form se fait en utilisant la super variable $_POST qui est elle aussi un tableau de type associatif mis à disposition par le serveur PHP.
Le nom, du couple nom/valeur, est alors l'attribut name se trouvant dans les éléments du formulaire dans ce tableau.

<input type="text" name="code_postal" value="">

Au niveau de la page de récupération des données :

$le_code_postal = $_POST['code_postal'];

Exercice n°23

  1. créez une page PHP nommée depart_form.php et une page arrivee_form.php
  2. dans la page depart_form.php, créez un formulaire envoyant la soumission vers la page arrivee_form.php
  3. le formulaire demande un pseudo, un email et un mot de passe
  4. récupérez et affichez les valeurs au niveau de la page arrivee_form.php

Cookie

Mis à mal par certaines compagnies, diabolisés par les médias, le cookie n'est qu'un fichier stocké sur l'ordinateur de l'utilisateur pouvant contenir au maximum 4ko d'information.
Sa syntaxe de création est la suivante :

setcookie(nom_cookie, contenu, valide_jusque, repertoire_concerné);
  • nom_cookie, nom permettant par la suite d'accéder au contenu ; respectez les règles de nommage des variables
  • contenu, l'information à conserver
  • valide_jusque, définit la date après laquelle le cookie sera détruit
  • repertoire_concerné, indique la portée du cookie sur un site

Par exemple, pour conserver un code postal :

$code_postal = '54000';
setcookie('cookie_du_site', $code_postal, time()+7*24*3600, '/');

Ce code va créer un fichier nommé cookie_du_site qui va contenir et sera accessible durant 7 jours à partir de l'instant de création du cookie à n'importe quel endroit du site.

Pour récupérer le contenu du cookie, il faut utiliser la super variable $_COOKIE qui est elle aussi un tableau associatif mis à disposition par le serveur PHP avec comme paramètre, le nom du cookie :

echo $_COOKIE['cookie_du_site'];    //affichera 54000

Exercice n°24

  1. créez une page PHP nommée depart_ck.php et une page arrivee_ck.php
  2. dans la page depart_ck.php, créez un bloc php où vous définissez un cookie
  3. ajoutez un lien dans la page depart_ck.php vers la page arrivee_ck.php
  4. récupérez et affichez le contenu du cookie sur la page arrivee_ck.php

Session

Chaque fois qu'un nouvel utilisateur accède au serveur, une session est créée et celle-ci permet de conserver le lien entre l'utilisateur et le serveur.
Pour accéder aux sessions, il faut qu'en début de code PHP figure :

session_start();

Le mécanisme de session utilise la super variable $_SESSION qui est un tableau associatif mis à disposition par le serveur PHP.
Pour créer une variable de session, il suffit de créer un indice dans ce tableau :

$_SESSION['mon_information'] = 'information importante conservée';

Pour récupérer le contenu, il suffit de lire le contenu :

echo $_SESSION['mon_information'];	//affiche 'information importante conservée'

Exercice n°25

  1. créez une page PHP nommée depart_sess.php et une page arrivee_sess.php
  2. dans la page depart_sess.php, créez un bloc php où vous activez les sessions
  3. sur cette page, créez une variable de session
  4. ajoutez un lien dans la page depart_sess.php vers la page arrivee_sess.php
  5. dans la page arrivee_sess.php, créez un bloc php où vous activez les sessions
  6. récupérez et affichez le contenu de votre variable de session sur la page arrivee_sess.php

Répéter une action : les boucles

Si beaucoup de choses vues jusqu'à présent ont déjà pu avoir été apprises sur Excel (les variables qui s'apparentent aux cellules, les tests logiques et les conditionnels), les boucles sont typiques de la programmation informatique.
Le but d'une boucle est de répéter une instruction (ou plusieurs) un certain nombre de fois ou d'itération.

Pour / for

Permet de répéter un lot d'instructions un nombre de fois connu ou déterminable au départ de la boucle.
La syntaxe est la suivante :

POUR compteur DE 1 A 10 FAIRE
    ECRIRE compteur
FINPOUR

Adapté à PHP, cela donne :

for($compteur = 1; $compteur <= 10; $compteur = $compteur + 1) {
    echo $compteur;
}

La syntaxe est la suivante : for (initialisation_compteur; condition_de_poursuite; pas_du_compteur) {}

  • initialisation_compteur : on initialise le compteur
  • condition_de_poursuite : définit la condition pour que la boucle soit répétée ; dès que la condition n'est pas respectée, la boucle s'arrête
  • pas_du_compteur : indique de combien on augmente le compteur à chaque passage de boucle
La condition de poursuite doit contenir un opérateur de comparaison

Une écriture simplifiée du pas existe : les opérateurs d'incrémentation ou de décrémentation :

$compteur++;	//équivalent à $compteur = $compteur + 1
$compteur--;	//équivalent à $compteur = $compteur - 1

Soit appliqué au parcourt d'un tableau

for($compteur = 1; $compteur <= 10; $compteur++) {
    echo $compteur;
}

Exercice n°26

Dans une page PHP

  1. créez un bloc PHP
  2. créez une boucle affichant 'etape N' où N va de 0 à 9 (incrémentation du pas)
  3. créez une boucle affichant 'etape N' où N va de 9 à 0 (décrémentation du pas)

Les tableaux possédant un indice numérique de type entier et les boucles font très bon ménage car en utilisant le compteur à la place de l'indice d'un tableau, il est possible de faire afficher le contenu du tableau.

Exercice n°27

Dans une page PHP

  1. créez un bloc PHP
  2. définissez un tableau $t_semaine contenant les jours de la semaines (ne précisez pas les index)
  3. créez une boucle affichant les jours de la semaine

Avant la version 7 de PHP, il n'était pas possible de faire une copie de tableau avec juste une instruction d'affectation entre deux tableaux. En effet, l'instruction suivante ne créait pas un nouveau tableau mais créait en réalité une référence :

$t_printemps = ['avril', 'mai', 'juin'];
$t_mois = $t_printemps;
$t_printemps[0] = '';   //écrase avril
echo $t_mois[0];        //contient ''

En fait, la deuxième instruction ne copiait pas le contenu mais faisait comme si une deuxième étiquette était posée sur la même "boite" : une seule boite mais avec 2 noms. Toute modification sur $t_printemps se retrouvait dès lors aussi sur $t_mois.
Pour faire une vraie copie de tableau, il fallait copier une à une les valeurs d'un tableau source dans un tableau cible et le mieux pour ça, était d'utiliser une boucle.

Exercice n°28

Dans une page PHP

  1. créez un bloc PHP
  2. reprenez le tableau $t_semaine contenant les jours de la semaines
  3. définissez un tableau $t_copie
  4. créez une boucle afin de transférer le contenu de chaque valeur de $t_semaine dans $t_copie
  5. affectez la valeur chaîne vide à $t_semaine à l'indice 2
  6. affichez la valeur de $t_copie à l'indice 2

Exercice n°29

En vous servant des boucles :

  1. créez un tableau tel que celui-ci contienne la valeur 999 à ses 10 emplacements
  2. créez un tableau tel que celui-ci contienne les valeurs allant de 1000 à 1010
  3. créez un tableau tel que celui-ci contienne les valeurs décroissantes allant de 90 à 80
  4. créez un tableau tel que les indices et les valeurs vont de 10 à 16
  5. créez un tableau tel que les indices vont de 10 à 16 (croissant) et les valeurs de 16 à 10 (décroissant)

Exercice n°30

En vous servant d'une seule boucle à chaque fois :

  1. créez deux tableaux, contenant tous les deux les valeurs allant de 20 à 29
  2. créez deux tableaux, tel que :
    • le 1er tableau contienne les valeurs allant de 25 à 34
    • le 2ème tableau contienne les valeurs allant de 30 à 39
  3. créez deux tableaux, tel que :
    • le 1er tableau contienne les valeurs paires entre 10 et 20
    • le 2ème tableau contienne les valeurs impaires entre 10 et 20
  4. créez deux tableaux, tel que :
    • le 1er tableau contienne les valeurs allant de 30 à 39 (croissant)
    • le 2ème tableau contienne les valeurs allant de 39 à 30 (décroissant)

Pour chaque / foreach

Si la boucle for convient parfaitement pour traiter les tableaux à indexage numérique, il n'en est pas de même pour les tableaux associatifs. C'est là l'intérêt des boucles foreach.
La syntaxe est la suivante :
foreach(tableau_assoc as alias_de_cle => alias_de_valeur) {}

  • tableau_assoc : le tableau associatif à parcourir
  • alias_de_cle : un alias donnant accès à la clé / indice en cours
  • alias_de_valeur : un alias donnant accès à la valeur correspondante à la clé en cours
$t_saison['printemps'] = 'avril, mai, juin';
$t_saison['ete'] = 'juillet, août, septembre';
$t_saison['automne'] = 'octobre, novembre, décembre';

foreach($t_saison as $ma_cle => $ma_valeur) {
    echo 'La saison nommée "' . $ma_cle. '" concerne ' . $ma_valeur . '.';
}

Cela affichera :

  • La saison nommée "printemps" concerne avril, mai, juin.
  • La saison nommée "ete" concerne juillet, août, septembre.
  • La saison nommée "automne" concerne octobre, novembre, décembre.

Dans le cas où avoir un alias pour la cle n'a pas d'utilité, une simplification existe :
foreach(tableau_assoc as alias_de_valeur)

foreach($t_saison as $ma_valeur) {
    echo 'La saison en cours contient ' . $ma_valeur . '.';
}

Exercice n°31

Dans une page PHP

  1. créez un bloc PHP
  2. reprenez le tableau sur les prénoms (exercice sur les tableaux associatifs)
  3. ajoutez une paire (prenom_B, "Bernard Brigite Blanche")
  4. ajoutez une paire (prenom_M, "Marie Marc Michel")
  5. définissez une boucle foreach affichant : pour la clé ...., on trouve les valeurs ...

Tant que / while

Lorsque le nombre d'itération ne peut être déterminé parce que la condition d'arrêt va être atteinte durant l'exécution des instructions itératives, il faut utiliser la boucle "tant que/while".
La syntaxe est la suivante :
while (condition_de_poursuite) {}

$compteur = 0;
while ($compteur < 10) {
    echo $compteur;
    $compteur++;
}

Comme pour la boucle for, la condition de poursuite indique à quel moment la boucle s'arrête : tant que la condition renvoie vrai, la boucle continue.

Les boucles infinies sont dûes à une condition d'arrêt qui n'est jamais rencontrée

Faire..tant que / do..while

Très similaire à la boucle "tant que", la boucle "faire ... tant que" permet d'être sûr que les instructions itératives sont réalisées au moins une fois.
La syntaxe est la suivante :
do {} while (condition_de_poursuite);

$compteur = 10;
do {
    echo $compteur;
    $compteur--;
} while ($compteur > 0);

Exercice n°32

Dans une page PHP

  1. créez un bloc PHP
  2. définissez une boucle while tel que suivant :
    • définissez une variable compteur et une variable somme
    • initialisez les deux variables à 0
    • compteur augmente de 1 à chaque passage
    • additionnez compteur à somme à chaque passage
    • la condition d'arrêt : somme est supérieur ou égale à 100
    • affichez la valeur de compteur et de somme
  3. même principe mais avec une boucle do...while ; la différence ?

Fonction

Une fonction n'est qu'une suite d'instructions que l'on isole afin de pouvoir réutiliser à loisir la suite d'instructions sans avoir à la ré-écrire entièrement.
L'intérêt réside dans la réutilisation d'une portion de code, l'externalisation d'un comportement et la facilité de maintenance.

Définition d'une fonction (= création)

La définition d'une fonction se découpe en 2 parties : la signature et le corps.

function ma_fonction()	//signature de la fonction
{	//début du corps
    instruction(s) de la fonction
}	//fin du corps de la fonction

La signature définit le nom de la fonction précédé de "function" et suivi de parenthèses ouvrante et fermante contenant le (ou les) argument(s) attendu(s) quand il y en a.
Il existe des fonctions attendant des arguments :

function ma_fonction(argument_1, argument_2)	    //signature de la fonction
{	//début du corps
    instruction(s) de la fonction
}	//fin du corps de la fonction

Les arguments sont des données qui doivent servir pour ce que doit faire la fonction.

Le nombre et l'ordre des arguments sont importants.

Le corps de la fonction est défini par les accolades ouvrante et fermante, et les instructions qui se trouvent entre elles. Les instructions définissent le comportement de la fonction, ce qu'elle va servir à faire.

function affiche_bonjour()
{
    echo 'Bonjour !';
}

Cette fonction sans argument écrit juste "Bonjour !".
La suivante calcule le prix TTC à partir d'un montant donné :

function affiche_prix_ttc($montant)
{
    $taux = 20;
    $prix_ttc = $montant * (1 + $taux / 100);
    echo 'prix TTC '.$prix_ttc.' &euros';
}

Si maintenant le taux est aussi une donnée variable, il faudrait modifier la fonction :

function affiche_prix_ttc_taux_variable($montant, $taux)
{
    $prix_ttc = $montant * (1 + $taux / 100);
    echo 'prix TTC '.$prix_ttc;
}
Deux fonctions ne peuvent avoir le même nom.

Si la fonction doit fonctionner avec différentes devises :

function affiche_prix_ttc_international($montant, $taux, $devise = '€')
{
    $prix_ttc = $montant * (1 + $taux / 100);
    echo 'prix TTC '.$prix_ttc.' '.$devise;
}

On ajoute un argument de plus. Noter la définition d'une valeur par défaut.

Un argument ayant une valeur par défaut, ne peut être suivi que d'un autre argument ayant une valeur par défaut également.

Appel d'une fonction (= utilisation)

Pour utiliser une fonction, il suffit de l'appeler en inscrivant le nom de la fonction suivi des parenthèses ouvrante et fermante contenant les argumentsattendus s'il y en a :

affiche_bonjour();

Lors de l'appel :

  • il n'y a plus le mot clé "function"
  • les arguments doivent être transmis dans l'ordre, soit directement, soit via une variable.

Appel directement avec les valeurs :

affiche_prix_ttc(9.99);
affiche_prix_ttc_international('19.25', '3', '$')

ou indirectement avec l'utilisation de variables contenant les valeurs :

$montant_panier = 100;
$tva_applique = 20;
affiche_prix_ttc($montant_panier, $tva_applique);

Portée de variable

Le nom des arguments attendus et celui des arguments transmis peuvent être identiques mais les variables sont différenciées : les variables sont à des niveaux différents et ne se percutent pas du fait de leur portée respective.

//définition de la fonction
function affiche_prix_ttc($prix, $taux)
{
    $prix_ttc = $prix * (1 + $taux / 100);
    echo 'prix TTC '.$prix_ttc;
    $prix = 999999;	    //modification du contenu de la variable $prix
    $toto = 'test d\'affichage';
}
//appel de la fonction
$prix = 100;
$taux = 20;
affiche_prix_ttc($prix, $taux);
echo $prix;	    //affichera 100 et non 999999
echo $toto;	    //n'affichera rien car n'existe pas en dehors de la fonction
Les variables définies au sein d'une fonction (signature ou corps), ne sont accessibles qu'au sein de cette fonction ; elles sont appelées variables locales.

Exercice n°33

Dans une page PHP

  1. créez un bloc PHP
  2. définissez une fonction qui affiche le texte "Bienvenue !"
  3. faîtes un appel à cette fonction
  4. modifiez la fonction de manière à ce qu'elle accepte un argument, le prénom afin d'afficher "Bienvenue Marc !"
  5. faîtes un appel à cette fonction en transmettant un prénom en argument
  1. créez une fonction qui affiche 5 fois le mot "encore"
  2. utilisez une boucle pour la répétition
  3. faîtes un appel à cette fonction
  4. modifiez la fonction afin qu'elle accepte une valeur entière "n" en argument
  5. cette fonction affiche autant de fois le mots "encore" que "n"
  6. faîtes un appel à cette fonction en transmettant la valeur entière
  7. modifiez la fonction afin qu'elle accepte un autre argument, le mot à afficher
  8. faîtes un appel à cette fonction en transmettant la valeur entière et le mot à afficher

Pour aller plus loin voir les mots clés "global" et "static".

Mot clé return

Sémantiquement, une distinction est faite entre fonction et procédure selon que :

  • une fonction renvoie/retourne un résultat
  • une procédure ne renvoie pas de résultat ; généralement, il y a un affichage ou un process pour conserver une information (mise en base de données, inscription dans un fichier, etc.).

L'intérêt de renvoyer un résultat est que celui-ci peut être réutilisé à un autre endroit, soit directement dans le code de la page, soit par une autre fonction.
Pour cela, le résultat retourné par une fonction peut être placé dans une variable ou la fonction elle-même peut être directement utilisée :

//définition de la fonction
function renvoie_prix_ttc($prix, $taux)
{
    $prix_ttc = $prix * (1 + $taux / 100);
    return $prix_ttc;
}
//création d'une procédure
function affiche_prix_ttc($p)
{
    echo 'prix TTC '.$p;
}

Pour retourner un résultat, il suffit de placer dans le corps de la fonction le mot clé "return" suivi de la valeur à renvoyer.
Lors de l'appel de la fonction, on peut donc définir une variable qui va capter le résultat ou utiliser directement la fonction. On peut ensuite imaginer une deuxième fonction qui se charge de l'affichage.

//appel des fonctions
$prix = 100;
$taux = 20;
$montant = renvoie_prix_ttc($prix, $taux);
affiche_prix_ttc($montant);
//peut se simplifier ainsi :
affiche_prix_ttc(renvoie_prix_ttc($prix, $taux));

Exercice n°34

Dans une page PHP

  1. faire une fonction qui affiche le nombre 2
  2. faire une fonction qui affiche 3 et retourne 4
  3. faire une fonction qui retourne 5 et affichez le résultat retourné par cette fonction
  4. faire une fonction qui retourne 6 et placez la valeur dans une variable
  5. faire une fonction qui retourne 7 et une fonction qui affiche la valeur transmise en un argument (qui n'est autre que le résultat retourné par la fonction juste avant)
Un seul résultat peut être transmis avec un return.
Aucune instruction inscrite après une instruction "return" n'est réalisée.

Après qu'une instruction "return" ait été réalisée à l'intérieur du corps d'une fonction, le programme quitte la fonction. Dès lors, toutes les instructions d'une fonction après un return ne sont jamais exécutées.

function affiche_prix_ttc($prix, $taux)
{
    $prix_ttc = $prix * (1 + $taux / 100);
    return $prix_ttc;	//-> quitte la fonction
    echo 'test d\'affichage';	//instruction jamais réalisée car située après un return
}

Certaines simplifications peuvent être faites en tenant compte de ce principe :

function get_le_plus_grand($num_1, $num_2)
{
	if ($num_1 >= $num_2) {
        return $num_1;
	} else {
        return $num_2;
	}
}

Simplifiée ainsi :

function get_le_plus_grand($num_1, $num_2)
{
	if ($num_1 >= $num_2)
        return $num_1;
    return $num_2;
}

On retire le else qui ne sert à rien.

Exercice n°35

Dans une page PHP

  1. créez un bloc PHP
  2. définissez les fonctions pour :
    • valeur au carré
      1. définissez une fonction qui attend un argument et renvoie la valeur transmise après l'avoir mise au carré
      2. affichez ensuite le résultat dans le corps de la page
    • valeur absolue (retourne 8 si reçoit -8 ou 8)
      1. définissez une fonction qui renvoie la valeur absolue de la variable transmise en argument
      2. affichez ensuite le résultat dans le corps de la page
    • le plus grand nombre en valeur absolue
      1. définissez une fonction qui renvoie la valeur absolue la plus grande entre 2 valeurs transmises en argument
      2. affichez ensuite le résultat dans le corps de la page
    • le plus grand nombre parmi 3 entiers
      1. définissez une fonction qui accepte 3 entiers et renvoie la valeur la plus grande des 3
      2. faire de même avec une fonction qui accepte 2 entiers uniquement ; trouver la valeur la plus grande des 3
Remarques
  • Une fonction peut être appelé à l'intérieur d'une autre fonction.
  • Une fonction peut être l'argument d'une autre fonction.

Fichiers externes

Include et require permettent d'appeler un fichier externe.

require 'le_chemin_vers/mon_fichier';

ou

include 'le_chemin_vers/mon_fichier';

La différence entre les deux porte sur le fait que dans le cas où le fichier ne peut pas être trouvé :

  • avec include, il est possible de "gérer" l'erreur
  • avec require, le programme est interrompu

Require est donc plus sûr car il stoppe l'exécution.

Exercice n°36

Dans une page PHP

  1. créez un nouveau fichier PHP, nommez le "fonction.inc.php" par exemple
  2. dans ce fichier, inscrivez les balises ouvrante et fermante de PHP
  3. couper, coller la fonction qui affiche "Bienvenue" de l'exercice sur les fonctions
  4. dans votre page d'affichage, faite un import du fichier et appelez la fonction.