Sur le Web, la plupart d'entre nous sommes des clients qui sollicitent avec un navigateur,un serveur distant en leur demandant, via une requête HTTP(S), une page Web.
Si la page Web existe, le serveur fait une réponse au client et le client obtient la page Web.
On appelle serveur à la fois la machine et l'application (par exemple APACHE) qui est capable de gérer plusieurs requêtes de clients différents "simultanément".
On dit qu'une page Web est dynamique si elle peut varier en fonction de l'interaction avec le client.
Le langage PHP (Personal Hypertext Preprocessor), installé sur le serveur, permet de rendre une page Web dynamique.
Sur un serveur est aussi installé un SGBD comme MariaDB pour gérer une base de données.
On pourrait installer séparément chacune de ces applications sur un ordinateur personnel, mais il existe un paquet par exemple XAMPP, (A pour Apache, M pour MariaDB,P pour PHP) qui permet d'installer toutes ces applications sur votre ordinateur personnel, pour vous permettre de tester sur votre ordinateur personnel l'architecture client-serveur.
Le langage PHP (Personal Hypertext Preprocessor) interprète le code PHP, inséré dans une page HTML, entre les balises <?php et ?>, et le transforme en code HTML.
Par exemple, copier le code ci-dessous, enregistrer le sous le nom test1.php dans le dossier htdocs
<!DOCTYPE html >
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>PHP</title>
</head>
<body>
<p> Ceci est un paragraphe </p>
<?php
echo('<p> Voici un deuxième paragraphe </p>');
?>
</body>
</html>
Lancer XAMPP puis dans l'URL entrer localhost/test1.php
On observe alors
Tout se passe comme si la page HTML suivante a été récupérée par le client
<!DOCTYPE html >
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>PHP</title>
</head>
<body>
<p> Ceci est un paragraphe </p>
<p> Voici un deuxième paragraphe </p>
</body>
</html>
PHP est un langage de programmation
On peut utiliser des variables, dont le nom est toujours précédé du symbole $, par exemple:
<body>
<?php
$jour = date("d/m/Y");
echo('< p > Bonjour!</p>');
echo ("Nous sommes le $jour") ;
?>
</body>
</html>
On observe alors
Par contre si on écrit
echo ('Nous sommes le $jour') ;
Dans ce cas on observe
Pour qu'une variable à l'intérieur d'une chaîne de caractères soit évaluée, il faut encadrer la chaîne de caractères par des guillemets doubles
L'interactivité sur le Web est souvent géré par des formulaires
Par exemple on demande à l'utilisateur d'entrer dans une zone de saisie son année de naissance, ensuite en retour sera affiché l'âge de l'utilisateur sur une autre page (première méthode) ou sur la même page (deuxième méthode)
Première méthode
Dans une simple page html age.html on récupère l'année de naissance, puis dans une page php age.php on fait le traitement
Voici la page age.html
<!DOCTYPE html >
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Age</title>
</head>
<body>
<form action="age.php" method="get">
<p> Quelle est votre année de naissance ? </p>
<input type="text" name="annee" value=""/>
</form>
</body>
</html>
Tester cette page en entrant une année
Il ne se passe rien quand vous faîtes Entrée après avoir entré une année dans la zone de saisie, c'est normal car la page de traitement n'existe pas encore. Il faut faire la page de traitement
Voici la page age.php
<!DOCTYPE html >
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Age</title>
</head>
<body>
<?php
$annee = date("Y");
$age = $annee - $_GET["annee"];
// à compléter
?>
</body>
</html>
On observe
Il existe deux méthodes pour la transmission d'une page, la méthode GET et la méthode POST
Dans la page html l'attribut methode de la balise form avait pour valeur get
Par l'intermédiaire d'un dictionnaire $_GET on récupère ce qui a été saisi comme année de naissance
Voilà pourquoi on calcule l'âge grace à l'instruction
$age = $annee - $_GET["annee"];
En utilisant echo faire afficher dans la page de traitement le message suivant
Vous avez .... ans
A la place des points de suspension, l'âge en rapport de l'année de naissance
Vous avez observé dans l'URL après le point ?, lors du passage de l'information annee de la page age.html à la page age.php, la valeur de annee
Changer de méthode de transmission, utiliser la méthode POST, et utiliser le dictionnaire $_POST
Deuxième méthode
Créer un fichier age2.php dans lequel il y a le formulaire et le traitement
Pour éviter que le texte concernant le traitement des données ne s'affiche dans la page même s'il n'y a pas de saisie de données, utiliser la fonction isset() sur la clé du dictionnaire $_POST que vous utilisez
En première nous avons codé le jeu Eisbar en JavaScript, nous allons Maintenant le coder côté serveur en PHP
Trois dés sont affichés
Il faut compter le nombre total de trous dans la glace, le nombre total d'ours sur la glace et le nombre total de poissons sous la glace
Le point central d'un dé est considéré comme un trou dans la glace
Les autres points sont vus comme des ours autour du trou Enfin les points à l'opposé sont vus comme des poissons de l'autre côté de la glace
Par exemple pour le dé suivant :
Il y a 1 trou, 2 ours et 4 poissons
Dans un fichier ice.php sera affiché 3 images de dé et un formulaire avec 3 zones de saisie
L'une pour le nombre de trous dans la glace
Les deux autres pour le nombre de poissons et d'ours
Le fichier de traitement sera sol_ice.php
Pour récupérer le contenu du tableau mémorisant le lancer des 3 dés d'une page à l'autre on se servira de la notion de session en PHP, car on ne peut pas utiliser $_POST puisque le lancer de dés n'est pas saisi dans un formulaire
Un dictionnaire global $_SESSION permet de mémoriser ce tableau
Télécharger et compléter les fichiers ice.txt et sol_ice.txt
On va créer la base de données films avec laquelle nous avons travaillé en cours et en exercices, voir ici
Le schéma relationnel de la base de données films est, avec la convention:
Film(idFilm,titre,année,genre,résumé,idRéalisateur,codePays)
Pays(code,nom,langue)
Artiste(idArtiste,nom,prénom,annéeNaiss)
Rôle(idFilm,idActeur,nomRôle)
Internaute(email,nom,prénom,région)
Notation(email, idFilm,note)
Où écrire du SQL pour créer une base de données ?
Lancer XAMPP
Sur le tableau de bord, à la ligne MySQL cliquer sur Admin, la page de phpMyAdmin va s'ouvrir
phpMyAdmin est un environnement graphique permettant de créer des bases de données et de les mettre à jour
On peut créer une base de données en cliquant sur Nouvelle base de données, sur le panneau de gauche
On va privilégier l'écriture de commandes en SQL
Sélectionner l'onglet SQL pour ouvrir une fenêtre permettant d'écrire du SQL
Puis cliquer sur Exécuter en bas à droite
Vous devez observer le message de validation suivant
Attention! En cas d'erreurs il est facile de supprimer une base de données et de recommencerEn utilisant la commande SQL
DROP DATABASE Nom_BD
De même on peut supprimer une table avec la commande
DROP TABLE Nom_Table
On va maintenant créer les tables de la base de données films
Pour garder une trace de ce que l'on a fait on va écrire les commandes SQL, dans un fichier .sql, les tester et ensuite mémoriser les commandes que si elles sont correctes
On doit respecter les contraintes référentielles de la base de données et créer en premier les tables sans clé étrangère
Commençons par écrire la table Artiste
On écrit à la fois dans le fichier films.sql et dans la fenêtre SQL de phpMyAdmin pour la base films
Cliquer ensuite sur Exécuter en bas de la fenêtre et normalement vous devez observer un message de validation
Si c'est validé on continue, sinon on corrige
Créer les tables Pays et Internaute
On va créer la table Film ayant deux clés étrangères
Puis la table Rôle dont la clé primaire est un couple
Créer la table Notation
Maintenant la base de données est crée mais vide!
Comment entrer les données ?
On peut récupérer de nombreuses données avec un fichier .sql déjà existant, par exemple ici
On va prendre quelques éléments de ce fichier et en ajouter d'autres "à la main" pour se familiariser avec les commandes de SQL
INSERT INTO Artiste (idArtiste, nom, prénom, annéeNaiss) VALUES
(1, 'Lucas', 'George', 1944),
(2, 'Hamill', 'Mark', 1951),
(3, 'Ford', 'Harrison', 1942),
(4, 'Fisher', 'Carrie', 1956),
(5, 'Cushing', 'Peter', 1913),
(6, 'Daniels', 'Anthony', 1946),
(31, 'Hanks', 'Tom', 1956),
(32, 'Wright', 'Robin', 1966),
(39, 'Mendes', 'Sam', 1965),
(40, 'Welles', 'Orson', 1915),
(42, 'von Trier', 'Lars', 1956),
(48, 'Bean', 'Sean', 1959),
(49, 'Bello', 'Maria', 1967),
(50, 'Deneuve', 'Catherine', 1943),
(53, 'Stormare', 'Peter', 1953),
(59, 'Besson', 'Luc', 1959),
(62, 'Willis', 'Bruce', 1955),
(64, 'Oldman', 'Gary', 1958),
(65, 'Holm', 'Ian', 1931),
(66, 'Tucker', 'Chris', 1971),
(68, 'Lang', 'Fritz', 1890),
(85, 'Depp', 'Johnny', 1963),
(99, 'Plummer', 'Amanda', 1957);
Entrez ces artistes avec cette syntaxe
Quel est l'id de Wim Wenders ? Comment fonctionne l'auto increment ?
Ajouter quelques artistes de votre choix, acteurs et réalisateurs
Inserer un dernier artiste en "auto increment" mais comme vous ne connaissez pas sa date de naissance, mettre la valeur NULL pour la date de naissance
En piochant quelques éléments dans le fichier .sql référencé ci-dessus, remplir les tables Pays, Internaute, Film, Rôle et Notation (attention à garder la base cohérente)
Compléter les données manquantes ou corriger les erreurs de la base en utilisant la commande
UPDATE Nom_Table SET attribut=valeur WHERE conditions
Par exemple, si j'ai fait l'insertion suivante
INSERT INTO Artiste(nom,prénom,annéeNaiss) VALUES
('Chaplin','Charlie',NULL);
Je peux mettre à jour ensuite en faisant
UPDATE Artiste SET annéeNaiss=1889
WHERE nom='Chaplin' and prénom='Charlie'
Entrez dans la table Rôle les rôles de l'acteur Harrison Ford dans le file 'Blade Runner' et dans le film 'Les aventuriers de l'Arche perdue'
Ensuite faire une requête d'interrogation 'afficher les noms des rôles de l'acteur Harrison Ford'
Insérer deux ou trois internautes
Puis insérer quelques notations de films
Ensuite faire des requêtes comme 'la note maximale' ou la moyenne des notes ou encore 'afficher les titres de films avec leur note'
Il faut tenir compte des contraintes référentielles
On ne peut pas supprimer un n-uplet contenant une clé primaire référencée par une clé étrangère, avant d'avoir supprimé tous les n-uplets contenant cette clé étrangère
Par exemple, si un on supprime un internaute, alors on doit vérifier qu'il n'existe pas de n-uplets dans la table Notation en lien avec cet internaute
Si c'est le cas on doit supprimer toutes les notations de cet internaute en premier, puis on supprime l'internaute
Expérimentez les situations décrites ci-dessus en utilisant la commande ci-dessous
DELETE FROM Table
WHERE conditions permettant d'identifier le n-uplet
Lorsque la base est assez remplie, on peut faire des interrogations intéressantes
Faire des requêtes d'interrogation
L'apport de PHP est de rendre l'interrogation et la mise à jour de la base de données possible par un utilisateur ne maîtrisant pas le SQL, par l'intermédiaire d'une page php avec des formulaires
Il faut donc par programmation avec PHP, dans l'ordre :
PHP propose des extensions pour se connecter à une base de données
L'extension mysqli pour des SGBD de type MySQL, comme MariaDB
On peut soit utiliser le langage programmation objet, soit utiliser le langage de fonctions
On va utiliser ici le langage objet
<!DOCTYPE html >
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>PHP</title>
</head>
<body>
<php?
try
{
// choisir l'une des deux connexions suivant votre os
// connexion où os = windows
$link = new mysqli('localhost','root', '', 'films');
// connexion où os = mac
$link = new mysqli('localhost','root', 'root', 'films');
}
catch (Exception $e)
{
die(’Erreur : ’ . $e->getMessage());
}
echo 'Traitement à suivre...';
?>
</body>
</html>
Plusieurs raisons peuvent expliquer l'échec d'une connexion à une base de données, par exemple, vous vous êtes trompés sur le numéro de port, vous avez mal orthographié le nom de la base etc...
Ainsi on encadre la tentative de connexion par un try {} catch{} . Dans ce cas si la connexion a réussi, on fait ensuite le traitement sur la base, sinon on capture un objet $e de type Exception, et on récupère uniquement le message d'erreur par la méthode getMessage()
La syntaxe est $e ->getMessage()
Pourquoi en PHP on n'écrit pas $e.getMessage() ?
localhost' ou '127.0.0.1' est le nom de l'hôte ici. Si c'est un serveur distant ce sera un nom de domaine d'un hébergeur de site par exemple
PDO (PHP Data Objects) est une extension de PHP qui définit une interface uniforme pour accéder aux bases de données en PHP.
Expérimentez et faites des erreurs par exemple avec le nom de la base
Dans un premier temps on va effectuer une requête statique (sans variable), par exemple on va demander d'afficher les noms et prénoms des artistes dont l'année de naissance est supérieure ou égale à 1950, ordonnés dans l'ordre croissant
En SQL cela donne
SELECT nom,prénom,annéeNaiss FROM Artiste
WHERE annéeNaiss >= 1950 ORDER BY annéeNaiss
En PHP cela donne (PDO)
On observe alors (une partie seulement)
On applique la méthode query sur l'objet $link
Le paramètre de la méthode est $query
On récupère des données $data sur lesquelles on va pouvoir itérer ligne par ligne
Ecrire d'autres requêtes statiques par contre modifier l'affichage et s'il le faut ne pas se contraindre d'afficher les résultats dans un tableau html
On aimerait rendre les requêtes variables
Dans un premier temps on va simplement reprendre la requête précédente et rendre variable l'année de naissance minimale à partir de laquelle on veut afficher les artistes
On va créer un seul fichier php dans lequel on va mettre un formulaire où l'utilisateur entre cette année minimale
Quand il clique sur envoyer on observe alors avec les valeurs de la base
Créer un nouveau fichier .php et insérer la partie suivante, et compléter avec la connexion à la base de données et le formulaire
On va faire une deuxième requête préparée avec plusieurs variables, et cette fois ci pour insérer des artistes
Au lieu d'écrire
// on utilise l'auto-incrémentation
$query = 'INSERT INTO Artiste(nom,prénom,annéeNaiss) VALUES
(?,?,?)';
$date = $link -> prepare($query);
$data -> execute(array($_POST['nom'],$_POST['prenom'],$_POST['annee']));
// puis lecture ligne à ligne
on préfère rendre significatifs les points d'interrogation, par des paramètres :nom,:prenom,:annee, puis on associe les paramètres par les valeurs entrées via un tableau associatif
// on utilise l'auto-incrémentation
$query = 'INSERT INTO Artiste(nom,prénom,anneeNaiss) VALUES
(:nom,:prenom,:annee)';
$date = $link -> prepare($query);
$data -> execute(array(':nom' => $_POST['nom'],
':prenom' => $_POST['prenom'],
':annee' => $_POST['annee']));
// puis lecture ligne à ligne