php
php permet de générer programmatiquement des morceaux de page web. Un fichier php est donc formaté exactement comme un fichier html mais possède en plus des balises encadrant des blocs de code qui seront exécutés à l’endroit où ils sont placés dans le html.
L’exemple qui suit est un fichier php complet. Sauvegardé en tant que hello.php
et placé sur un serveur interprétant le php, il fabriquera une page web contenant le paragraphe Hello World et un tableau des caractéristiques de la version de php installée.
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php echo '<p>Hello World</p>'; ?>
<br />
<?php phpinfo(); ?>
</body>
</html>
Une des utilisations de php est la saisie par l’utilisateur d’information dans un formulaire et la sauvegarde et le traitement de ces informations sur le serveur. Les formulaires sont toujours les balises form
vues précédemment, mais deux nouvelles particularités apparaissent : des attributs action
et method
pour l’élément form
indiquant respectivement le script php à appeler quand le formulaire sera soumis et la méthode http à utiliser ; et un élément input de type submit
(il s’agit d’un bouton dont l’appui va engendrer l’appel à l’action mentionné au dessus).
<form action="traitement.php" method="get">
<input type="text" name="champ"></input>
<input type="submit" value="Soumettre le formulaire" />
</form>
Notons que ceci ne contient pas de balise <?php
, cela peut donc être sauvé dans un fichier html
.
Le fichier traitement.php
quant à lui manipulera les résultats dans une page web. Il peut accéder aux valeurs stockées dans le formulaire via un dictionnaire nommé $_REQUEST
.
<?php
echo("Champ valait " . $_REQUEST["champ"]);
?>
Exercices
Les scripts php
nécessitant un serveur, nous allons installer un serveur apache sur une machine virtuelle.
Lancer Virtualbox et démarrer la VM Ubuntu_1804
(sans X).
Dans le terminal, installer apache (serveur HTTP) et php à l’aide de la commande suivante :
sudo apt update
sudo apt install libapache2-mod-php
S’il est demandé, donner le mot de passe de robert qui est leffe.
On peut maintenant consulter les pages servies par le serveur depuis la machine réelle en pointant le navigateur vers : http://192.168.56.101/1.
Pour simplifier le travail, nous allons créer sur la VM un dossier pour vos applications web et l’attribuer à l’utilisateur robert :
sudo mkdir /var/www/html/app
sudo chown robert /var/www/html/app
Écrire le fichier php donné au dessus et le sauver sous le chemin /var/www/html/app/hello.php
.
Consulter l’URL http://192.168.56.101/app/hello.php.
Les erreurs seront stockés dans le fichier /var/log/apache2/error.log
.
Comme il sera plus simple d’éditer les fichiers sur la machine réelle et de les transférer ensuite vers la VM, nous pourrons utiliser scp.
scp chemin utilisateur@ip:cheminvm
Par exemple pour transférer un fichier x.php dans le dossier app, la commande sera :
scp x.php robert@192.168.56.101:/var/www/html/app/
Enquête
Nous souhaitons réaliser une enquête auprès des utilisateurs du site pour savoir s’ils sont pour ou contre les enquêtes.
Réaliser un formulaire web demandant à l’utilisateur ses nom, prénom et date de naissance, ainsi que son avis (pour ou contre).
Pour la date de naissance, on pourra utiliser un input de type
date
qui permet de choisir dans un calendrier avec certains navigateurs.Créer un fichier
php
qui récupère les valeurs entrées par l’utilisateur et les affiche de façon agréable (pour permettre à l’utilisateur de visualiser ses réponses avant de les valider).Plutôt que la date de naissance, on pourra calculer et afficher l’age de l’utilisateur.
Fonctions utiles :
Ajouter au dernier fichier un bouton qui permet d’une part de sauvegarder les données sur disque et d’autre part d’afficher les statistiques de réponses.
Pour écrire dans un fichier, il faut d’abord obtenir un descripteur de ce fichier avec la fonction fopen, écrire avec la procédure fwrite et fermer le fichier avec fclose.
// j'ouvre le fichier nommé resultats.txt en mode ajout (a) pour // écrire dedans et ne pas effacer ce qu'il contient (les autres modes // sont 'r' pour lire et 'w' pour écraser). // Attention aux droits nécessaires pour créer le fichier !!! $fd = fopen("resultats.txt", "a"); // j'écris dans le fichier fwrite($fd, "truc\n"); // je relache le descripteur de fichier et ne pourrai plus écrire fclose($fd);
Enfin réaliser la page affichant les statistiques. Elle doit lire le fichier créé précédemment, afficher le nombre de pour et de contre, ainsi que les pourcentages. Elle doit aussi afficher l’age moyen des personnes interrogées.
La lecture dans un fichier se fait avec la fonction fread. On peut ensuite transformer le résultat en un tableau de lignes à l’aide de la fonction explode
Mot de passe et traque des utilisateurs
Nous souhaitons maintenant que les utilisateurs de notre site puissent s’identifier pour accéder à du contenu personnalisés. Nous allons donc leur proposer de choisir un identifiant et un mot de passe.
Plusieurs questions se posent :
- Comment allons-nous sauvegarder ces informations ?
- Comment ne pas redemander ses identifiants à l’utilisateur à chaque retour sur le site ?
Faire une version naïve de la page de création de compte qui demande login et mot de passe et sauvegarde cela tel quel dans un fichier.
Est-il possible de mettre des droits sur le fichier interdisant aux autres élèves de le lire tout en permettant au site web de lire le fichier ?
En pratique, on ne stocke pas les mots passe en clair mais on sauvegarde un hash2 du mot de passe salé3. En php, on peut utiliser la fonction crypt.
Avertissement : la sécurisation des mots de passe est un problème difficile. Les quelques lignes précédentes ne présentent que quelques uns des écueils que rencontre le développeur voulant réaliser cette opération lui-même. Un développeur web consciencieux doit utiliser des bibliothèques de gestion des mots de passe fiables et réputées et non une solution ad-hoc.
Cookies
Pour ne pas redemander les mêmes informations plusieurs fois à un utilisateur (par exemple son login et son mot de passe) et retenir des informations liées à l’utilisateur (par exemple s’il a déjà répondu au sondage) sur sa propre machine plutôt que le serveur, on utilise des cookies. Les cookies sont donc à la fois une bonne chose pour l’utilisateur en simplifiant sa navigation et permettant de lui proposer des contenus en accord avec ses choix et un outil de suivi et donc de traque des utilisateurs (par exemple les boutons j’aime de facebook stocke dans un cookies les pages visitées contenant ce bouton) pouvant porter à la vie privée de l’utilisateur. Leur utilisation est d’ailleurs encadrée par la CNIL et la commission européenne.
La procédure setcookie permet de sauver une chaîne de caractères (le nom du cookie) dans un cookie. Cette procédure ne peut, d’après la norme HTTP, être utilisée qu’avant tout contenu html (c’est-à-dire avant le doctype). Une fois un cookie nommé
exemple
entré, on peut accéder à son contenu par l’intermédiaire du dictionnaire$_COOKIE
. On ne peut de plus pas lire les cookies aussitôt qu’ils ont été écrits (si une page crée un cookie, il sera nécessaire de recharger la page pour que le dictionnaire$_COOKIE
soit rempli).Aux pages web précédentes ajouter du code créant un cookie nommé visites et contenant la liste des pages web visitées séparées par des
#
. On peut accéder au chemin de la page via$_SERVER['REQUEST_URI']
($_SERVER
est un dictionnaire contenant les informations de connexion).Réaliser une page web sur laquelle l’utilisateur atterrira après avoir saisi son login et sont mot de passe. Dans cette page web, deux cookies seront créés : un pour le login, un pour le hash du mot de passe. Réaliser une troisième page web qui teste si les cookies existent, si c’est le cas les vérifie auprès du serveur, sinon proposent à l’utilisateur de s’enregistrer.
En salle Ritchie, au lieu de la machine réelle, on utilisera une deuxième machine virtuelle (la
XUbuntu_1804
).↩︎Une fonction de hash (ou fonction de hachage en français) transforme de façon injective son entrée en un représentant nommé hash. Et la fonction inverse (qui au représentant associe l’entrée initiale) est difficile. Pour vérifier un mot de passe, on calculera donc son hash et tentera de vérifier si c’est celui qui est sauvegardé. Mais si quelqu’un obtient la liste des hash, il ne pourra pas facilement en déduire les mots de passe de chaque utilisateur. Certaines vieilles fonctions de hashage ne doivent plus être utilisées car la fonction inverse n’est plus assez difficile, c’est par exemple le cas de md5.↩︎
Un sel est un texte que l’on ajoute au mot de passe avant de calculer le hash. En effet, les fonctions de hash sont connues et les crackers disposent de rainbow tables associant les mots de passe classiques à leurs hash. Chaque site ayant un sel intelligemment choisi sera moins soumis au risque de découverte de nombreux mots de passe par rainbow tables. Ce n’est cependant pas suffisant pour assurer la sécurité une fois la base de données de mots de passe connue, car je connais alors le mot de passe de tous ceux ayant utilisé le même mot de passe que moi…↩︎