Dans cette partie, nous allons étudier comment créer un Serveur Web Dynamique en utilisant le langage PHP.
PHP est un langage de scripts généraliste qui, lorsqu'il est intégré à un serveur Web (comme Apache),
permet de générer dynamiquement des pages web (contenant potentiellement du HTML, CSS et Javascript).
NB: PHP peut aussi être utilisé pour créer une API REST qui génère du JSON.
Environnement de Travail
Pour créer notre serveur web en php, il nous faut un serveur web capable d'exécuter les scripts
PHP...
De plus, un serveur PHP est généralement couplé à un serveur de base de données comme MySQL.
Pour toutes ces raisons, nous allons utiliser une solution "classique" qui fournit à la fois un serveur
Apache, un serveur MysSQL, et divers outils d'administration tels que phpMyAdmin :
XAMPP.
Votre premier travail consiste donc à télécharger et installer la (dernière) version de
XAMPP qui correspond à votre
système d'exploitation.
Pour vérifier que tout est ok, utilisez l'interface de XAMPP pour démarrer les serveurs Apache et MySQL
(si ce n'est pas déjà fait). Dans le menu d'administration (Dashboard) vous pouvez cliquer sur le
lien PHPInfo (en haut à droite de la page web) et admirer les informations de configuration du
serveur Apache, ainsi que sur phpMyAdmin pour accéder au contenu du serveur MySQL.
NB: sous Windows, il faut lancer le programme en tant qu'Administrateur.
Premier Script PHP
Les serveurs Apache vont chercher les fichiers demandés par l'utilisateur dans un dossier qu'on appelle
DocumentRoot.
Vous pouvez voir la valeur de DocumentRoot en cliquant PHPInfo dans le DashBoard.
Trouvez le dossier correspondant à DocumentRoot (a priori C:/xampp/htdocs/ sous Windows),
et créez un sous dossier nommé web3.
Dans web3 utilisez un éditeur de code (par exemple
Atom)
et créez le fichier index.php, avec pour contenu :
NB: lorsque seul le nom du dossier est indiqué (ex. http://localhost/web3/), le serveur web
renverra automatiquement le fichier nommé index.html, et s'il ne le trouve pas,
il cherchera index.php
C'est ce que nous faisons ici : demander http://localhost/web3/ revient en réalité à
obtenir la page http://localhost/web3/index.php .
Vous devriez obtenir le résultat suivant :
Résultat
PHP dit Hello World
NB: Si cela ne fonctionne pas, il est possible que votre serveur ait été démarré sur un port non standard.
Pour le vérifier, regardez l'adresse à laquelle vous aviez ouvert le DashBoard. Si l'adresse contient
un chiffre comme dans http://localhost:8080/dashboard, cela signifie que votre serveur sert les pages web
sur le port 8080. Vous devez alors aussi indiquer ce port particulier pour consulter vos propres
pages (ex. http://localhost:8080/web3/)
Affichage des erreurs
Lorsque vous développez en PHP, il est possible que le serveur Web qui exécute vos pages
n'indique pas les erreurs d'exécutions. Dans ce cas, si une erreur survient, le script
s'arrête (plante), mais vous n'avez aucune information vous permettant de savoir ce qui
s'est passé.
Ce fonctionnement est tout à fait logique lorsque votre site Web est en production :
il serait malvenu qu'un site Web affiche des messages d'erreurs incompréhensibles
(ou contenant des données sensibles) aux utilisateurs.
Par contre, pendant le développement, avoir le détail de ce qui a mal fonctionné peut
largement vous aider dans le but de corriger le problème.
D'une manière générale :
En développmement : on laisse PHP afficher les erreurs dans la page.
En production : on empêche PHP d'envoyer ses messages d'erreur à l'utilisateur.
Dans ce cours nous serons en mode développement : si le PHP de votre serveur Web n'affiche
pas les erreurs d'un de vos scripts, vous pouvez ajouter ces quelques lignes
au tout début :
NB : au lieux d'ajouter ces lignes au début de chaque script qu'on veut tester, il est possible de
demander au serveur Web d'afficher/cacher les erreurs en modifiant ses fichiers de configuration
(ex. php.ini).
PHP + HTML/CSS/Javascript
Dans l'exemple précédent, vous pouvez constater que le résultat obtenu correspond (uniquement) au contenu
de la chaine passée en paramètre de la fonction php echo.
Si vous demandez au navigateur d'afficher le code source de la page, vous pourrez remarquer que le code
php a totalement disparu : il ne reste plus que le code html généré par l'appel à echo.
Lorsqu'on demande une page .php à un serveur web, le serveur envoie le fichier à
l'interpréteur PHP (ou préprocesseur) et tout le code php qui se trouve entre
les balises <?php et ?>est exécuté et remplacé dans la page web
par son résultat.
L'interpréteur PHP ne comprend que le code php :
tout code qui n'est pas du code php (ex. HTML, CSS, Javascript) est recopié à l'identique.
C'est le résultat de ce processus (le code interprété, résultat du pré-processing) qui est envoyé par le serveur
en réponse au client (le navigateur).
On peut donc avoir des fichiers .php tels que :
http://localhost/web3/01_balises.php
<html>
<head>
<title>Exemple <?php echo " de pré-processing PHP" ?></title>
<style>
.bleu{
color: <?php echo "blue" ?>;
}
</style>
</head>
<body>
<h2 class="bleu">
Voici un exemple de <span style="color:red"><?php echo "code généré par PHP" ?></span>
</h2>
</body>
</html>
Résultat : le code dans les 3 balises <?php ... ?> a été interprété/remplacé.
Exemple de pré-processing PHP
Voici un exemple de code généré par PHP
Il est très important de bien comprendre que, comme dans cet exemple, le code php peut
générer du HTML, du CSS et/ou du Javascript, mais
il ne peut pas interagir avec ces langages : en effet,
les scripts PHP sont traités exclusivement sur le serveur,
alors que les autre langages s'exécutent sur le client, c.a.d. dans le navigateur.
Ils ne partagent donc aucunement le même contexte d'exécution (variables, etc.).
Les Bases du Langage
Code PHP
Le code php doit être écrit entre les balises
<?php et ?>.
Chaque instruction doit se terminer par un ; .
Comme nous venons de le voir, tout ce qui est en dehors de ces balises est ignoré par PHP
(ou plutôt, laissé tel quel).
La balise fermante ?> ne signifie pas la fin
d'un script : l'interpréteur continuera son exécution avec le même contexte (variables, fonctions, etc.)
dès qu'il rencontrera une nouvelle balise <?php.
Le code est donc exécuté séquentiellement de balise en balise en partageant (faisant évoluer)
le même contexte d'exécution.
C'est ce que nous allons voir ci-après, en particulier avec l'utilisation de variables.
Sorties en PHP : echo
C'est l'instruction echo qui sert principalement à faire des sorties dans une page :
<?php
echo "<p>Voici une sortie en PHP</p>" ;
?>
Résultat
Voici une sortie en PHP
Notez que <?= est une variante courte de <?php echo :
<?= "<p>Voici une autre sortie en PHP</p>" ?>
Résultat
Voici une autre sortie en PHP
Les Variables
Les variables php doivent être déclarées avec le pattern $nom_variable.
Leur portée est limitée au bloc dans lequel elles sont déclarées.
Le typage est dynamique. Il n'est pas obligatoire d'initialiser la valeur d'une variable, mais c'est
fortement conseillé.
http://localhost/web3/02_variable.php
<?php
$ma_variable = 5 ; // déclaration|affectation de variable
?>
<p>
Voici la valeur de ma variable : <?= $ma_variable ?>
</p>
<?php $ma_variable *= 2 ?>
<p>
Et la voici après avoir été modifiée : <?= $ma_variable ?>
</p>
Résultat
Voici la valeur de ma variable : 5
Et la voici après avoir été modifiée : 10
NB: Vous pouvez constater que le contexte d'exécution est bien partagé par les balises.
Informations sur une variable : var_dump(...)
Quand on développe un site web en php, il est parfois utile de pouvoir afficher simplement
(par ex. pour débugger) les informations concernant une variable.
La fonction var_dump(data) affiche les informations
concernant une data.
<?php $ok = false ; ?>
<p>Voici les informations sur $ok : <b><?php var_dump($ok) ?></b></p>
Résultat
Voici les informations sur $ok : bool(false)
Existence d'une variable : isset / unset
Cela peut sembler bizarre a priori (développer en PHP ne rend pas amnésique),
mais nous verrons qu'en PHP, il est souvent pratique de pouvoir vérifier si une variable existe.
(Ce sera en particulier le cas lorsque nous aurons à traiter des variables
correspondant à des champs de formulaires remplis, ou pas...).
La fonction isset(variable) renvoie true
si variable existe et est différente de null, false sinon.
La fonction unset(variable) permet de "détruire" une
variable.
Les chaînes de caractères de PHP sont similaires à celles des autres langages.
On pourra cependant noter que l'opérateur de concaténation est ici le . .
<?php
$tab = ['a', 'b', 'c', 'd'] ;
?>
<p>Voici un tableau de taille <?php echo count($tab) ?> :</p>
<div style="font-family: Monaco ; font-size: 0.8em">
<div style="white-space: pre ;"><?php var_dump($tab) ?></div>
</div><br>
<p>
<?php
$case = 2 ;
// on peut utiliser les variables dans un echo :
echo "Le contenu de la case $case est $tab[$case]." ;
?>
</p>
Dans l'alphabet phonétique de l'OTAN,
le code "Charlie" signifie 'C'.
Fonctions de recherche dans un tableau
PHP offre plusieurs fonctions permettant d'effectuer des recherches dans un tableau :
in_array(valeur, tableau) :
renvoie true si valeur est dans tableau,
false sinon.
array_key_exists(clé, tableau) :
renvoie true si clé existe dans tableau,
false sinon.
array_search(valeur, tableau) :
renvoie la clé correspondante à valeur si valeur
est dans tableau, false sinon.
<?php
$week = ['lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche'] ;
$day = 'vendredi' ;
$idx = array_search($day, $week) ;
// NB: il faudrait vérifier que la réponse n'est pas false...
echo "$day est le jour n° " . ($idx+1). " dans la semaine" ;
?>
Résultat
vendredi est le jour n° 5 dans la semaine
Les Structures de Contrôle
Conditionnelle : if
La structure du if en PHP est classique. Les blocs sont délimités par des accolades.
Plusieurs formes sont disponibles selon les besoins :
Le code HTML/CSS/Javascript qui est placé dans un bloc php
(dans un { ... } ) est "recopié" par l'interpréteur seulement si ce bloc est exécuté.
Ce mécanisme peut être mis à profit lorsque l'on crée un script php qui intercale plusieurs "morceaux" de
code php dans du HTML.
NB: cela peut aussi rendre le code difficile à lire...
Pour plus de lisibilité, on peut utiliser la
syntaxe alternative
dans laquelle les accolades sont remplacées par des : et la fermeture de bloc est assurée
par (selon le cas) : endif, endwhile, endfor, endforeach,
ou endswitch.
Exemple avec un bloc if : ... else : ... endif ; :
Tu vas rentrer
<?php
$a_le_permis = false ;
?>
<?php if($a_le_permis) : ?>
<!-- apparait seulement si la condition est true -->
<span style="color: blue">en voiture :) </span>
<?php else : ?>
<!-- apparait seulement si la condition est false -->
<span style="color: red">à pieds :(</span>
<?php endif ?>
Résultat
Tu vas rentrer
à pieds :(
Un autre exemple avec un bloc foreach : ... endforeach ; :
<?php
$phonetic_alphabet=array(
"Alpha" => "A",
"Bravo" => "B",
"Charlie" => "C",
"Delta" => "D"
) ;
?>
<style>
.cell{
width: 50%;
border: 1px solid black ;
padding: 3px;
}
</style>
<table>
<tr><th colspan="2">Alphabet phonétique de l'OTAN</th></tr>
<?php foreach($phonetic_alphabet as $code => $char) : ?>
<!-- ce code HTML est intégré à la boucle -->
<tr>
<td class="cell"><?php echo $code ?></td>
<td class="cell" style="text-align: center"><?php echo $char ?></td>
</tr>
<?php endforeach ?>
</table>
Résultat
Alphabet phonétique de l'OTAN
Alpha
A
Bravo
B
Charlie
C
Delta
D
Les Fonctions
Les fonctions php ont une syntaxe proche de celle qu'on peut trouver dans la plupart des langages.
Comme pour les variables, le type des paramètres ne doit pas être indiqué.
Fonction sans paramètre
<?php
// déclaration de la fonction
function disBonjour(){
$msg = "Hello World" ;
echo "<p>$msg</p>" ;
}
// appel de la fonction
disBonjour() ;
disBonjour() ;
?>
Résultat
Hello World
Hello World
Fonction avec paramètre(s)
<?php
// déclaration de la fonction
function disBonjourA($nom, $ponctuation='!'){
echo "<p>Hello $nom $ponctuation</p>" ;
}
// appel de la fonction
disBonjourA('Greg') ;
disBonjourA('Greg', ':)') ;
?>
Résultat
Hello Greg !
Hello Greg :)
Fonction avec valeur de retour (return)
<?php
// déclaration d'une fonction qui retourne une chaine
function getGreetingMessage($nom, $ponctuation='!'){
$msg = "Hello $nom $ponctuation" ;
return $msg ; // <- l'exécution s'arrête ici !
}
?>
<h2><?php echo getGreetingMessage('Greg') ?></h2>
Résultat
Hello Greg !
Inclusion de Fichiers
De manière à apporter plus de modularité et de ré-utilisabilité, PHP offre plusieurs fonctions qui
permettent d'inclure/importer des fichiers externes dans un résultat.
L'inclusion d'un fichier signifie littéralement insérer la totalité de son code
à l'endroit où est appelée l'inclusion.
L'exécution du script est alors réalisée comme si le code inclus y était collé.
Ce mécanisme permet de réutiliser non seulement des suites d'instructions php, des variables php,
des fonctions php... MAIS AUSSI du code HTML/CSS/Javascript !
Cela s'avère très pratique par exemple lorsque l'on a besoin d'intégrer un header, un
footer, une navbar, ... qui sont typiquement des instructions
HTML/CSS/Javascript qui doivent se répéter à l'identique dans plusieurs pages d'un même site.
Il existe 4 instructions permettant d'inclure le code d'un fichier dans un script :
include(fichier) :
inclut les instructions du fichier à l'endroit où
include est appelé. Ne fait rien si le fichier n'est pas trouvé.
include_once(fichier) :
comme include, mais ne fait rien si fichier a déjà été inclus
(précédemment) dans le script. (Cela permet par exemple d'éviter des re-déclarations, une connexion
à un serveur externe alors qu'elle a déjà été faite, etc.).
Ne fait rien si le fichier n'est pas trouvé.
require(fichier) :
a le même fonctionnement que include, mais déclenche une erreur d'exécution du script php
si fichier n'est pas trouvé.
require_once(fichier) :
a le même fonctionnement que include_once, mais déclenche une erreur d'exécution
du script php si fichier n'est pas trouvé.
Un Exemple
On définit d'abord plusieurs fichiers destinés à être inclus.
Dans cet exemple ce seront les fichiers :
header.html : du code HTML pour le header du site.
footer.php : du code HTML + PHP pour le footer du site.
helpers.php : du code HTML + PHP (ici, l'ajout d'une balise link
pour un fichier .css, et la déclaration d'une fonction PHP nommée generateTitle.
hepers.css : des déclarations CSS utilisées dans helpers.php.
Remarques:
Les fichiers .html (avec du HTML "pur") peuvent aussi être nommés .php
(ex. header.php).
Les fichiers contenant du code PHP (+ HTML) doivent être nommés .php
(ex. footer.php).
Voici le contenu de ces fichiers :
header.html
<h1>Cours de PHP</h1>
<hr>
footer.php
<div style="width: 100% ; padding: 5px ; background: black ; color: white">
Ceci est une démo d'inclusions en PHP <?php echo phpversion() ?>
</div>
helpers.php
<link rel="stylesheet" href="helpers.css">
<?php
/**
* Génère une balise h1 avec un titre formaté
* @param $title
*/
function generateTitle($title){
// formatage du titre
$title = ucwords($title) ;
// génération du code HTML
echo "<h2 class='custom'>$title</h2>" ;
}
Il ne reste plus qu'à inclure ces fichiers aux endroits voulus : ici dans index.php.
(NB: dès que helpers.php a été inclus, la fonction generateTitle est disponible.)
index.php
<?php require_once "helpers.php" ?>
<!doctype html>
<head>
<meta charset="UTF-8">
<title>Test Inclusion</title>
</head>
<body>
<?php include "header.html" ?>
<?php generateTitle("introduction") ?>
<p>
bla bla blaaa
</p>
<?php generateTitle("serveurs web dynamiques") ?>
<p>
bla bla blaaa
</p>
<?php generateTitle("conclusion") ?>
<p>
bla bla blaaa
</p>
<?php include "footer.php"; ?>
</body>
</html>