PHP : les bases du les formulaires PHP
sommaire M2202 développement web Objectifs PPN : Échange de données client/serveur : principe. Éléments du langage. Formulaire de saisie. Liaison avec une base de données (en TD).
Les formulaires Les formulaires permettent de doter les pages web d'éléments interactifs qui assurent le dialogue entre les internautes et le serveur. Voici 2 exemple de structures simples pour un formulaire : <form method="get" action="url_de_traitement"> <label>votre nom : </label> <input type="text" size="20" name="user-name" /> <input type="submit" value="valider" /> </form> <form method="post" action="url_de_traitement"> <label>votre nom : </label> <input type="text" size="20" name="user-name" /> <button>valider</button> </form>
Les formulaires METHOD indique la méthode de transmission HTTP des données saisies dans le formulaire : POST est la valeur qui correspond à un envoi de données stockées dans le corps de la requête (les données sont cachées mais PAS CRYTÉES!!!) GET correspond à un envoi des données visibles dans l'url (séparées de l'adresse du script par un point d'interrogation) : à éviter mais pratique pendant la phase de mise au point si l'attribut METHOD est omis, il vaut "get" par défaut ACTION permet d'indiquer l'url absolue ou relative de la page qui recevra les informations du formulaire, lorsque l'on cliquera sur le bouton de validation. C'est généralement le nom d'un fichier script PHP. si l'attribut ACTION est omis, l'url sera celle du document courant REMA RQUE : si l'on a à faire à un formulaire d' upload, la balise <form> doit comporter l'attribut enctype et la valeur multipart/form-data.
1er exemple de formulaire Voici un premier exemple de formulaire (très simple) qui permet d'identifier le client. On veut : proposer au client de saisir son nom et son mot de passe, récupérer ces informations pour les traiter. Voici les échanges qui vont s'opérer entre CLIENT et SERVEUR. Client appelle la page formulaire1data.html Util : Mot passe : Retourne le code HTML de formulaire1data.html Client transmet les informations à la page formulaire1traiter.php username= userpwd= formulaire1data.html contient le code HTML qui permet de présenter le formulaire pour la saisie des données formulaire1traiter.php traite les informations envoyées par le client
1er exemple de formulaire Voici le code de formulaire1data.html qui permet d'identifier le client : formulaire1data.html <head> <title>mon premier formulaire</title> </head> <body> <form action="formulaire1traiter.php" method="get"> <p><label> Nom : </label><input type="text" name="username" /></p> <p><label> Mot de passe : </label><input name="userpwd" type="password" /></p> <input type="submit" value="ok" id="ok"/> </form> </body> </html> Le formulaire contient 2 zones de texte (username et userpwd), dont l'une est de type password (remplacement des caractères par des * à la saisie). Il faut toujours veiller à bien structurer les éléments de la page dans la perspective prochaine de leur appliquer une mise en forme par feuille de style. On ajoutera donc toujours un LABEL devant les en têtes : <label> Nom : </label> et un attribut ID ou CLASS sur les balises importantes <form id="login">, <input type="submit" value="ok" id="ok">
1er exemple de formulaire On appelle la page http://localhost/formulaire1data.html On obtient l'écran suivant : Saisie d'une valeur : Après un clic sur le bouton OK, les paramètres du formulaire sont transmis dans la barre d'url sous la forme champ1=valeur1 & champ2=valeur2 Le mot de passe http://localhost/formulaire1traiter.php?username=admin&userpwd=secret est en clair C'est le script formulaire1traiter.php qui reçoit les données. le serveur met en place AUTOMATIQUEMENT les informations sous forme d'un tableau associatif $_GET[]
1er exemple de formulaire REMARQUE 1 On doit utiliser les informations du tableau $_GET pour afficher les valeurs formulaire1traiter.php <?php $username = $_GET['username']; $userpwd = $_GET['userpwd']; // afficher les valeurs des variables echo "nom=$username<br>"; echo "mot de passe=$userpwd<br>";?> Le serveur reçoit les informations dans un tableau associatif <?php echo "<pre>".var_dump($_get)."</pre>";?> formulaire1traiter.php array (size=2) 'username' => string 'admin' (length=5) 'userpwd' => string 'secret' (length=5)
REMARQUE 2 1er exemple de formulaire On peut aussi utiliser la fonction extract($_get) Cette fonction va créer une variable pour chaque clé du tableau associatif $_GET. <?php extract($_get); // afficher les valeurs des variables echo "nom=$username<br>"; echo "mot de passe=$userpwd<br>";?> REMARQUE 3 Si les données sont transmises en méthode POST, on utilise le tableau $_POST (ou extract($_post)) Les données http://localhost/formulaire1traiter.php sont cachées
2cd exemple de formulaire : login Modifions notre manière de traiter les données. Cette fois ci, on ne construit qu'une seule page formulaire3.php. La page doit : proposer au client de saisir son nom et son mot de passe, récupérer ces informations pour les traiter. Voici les échanges qui vont s'opérer entre CLIENT et SERVEUR. Client appelle la page formulaire3.php Util : Mot passe : Retourne le code HTML généré par le traitement PHP de formulaire3.php Client transmet les informations (en mode POST) à la page formulaire3.php username= userpwd= formulaire3.php Lors du 1er appel de cette page, aucun paramètre n'est transmis. formulaire3.php reçoit maintenant 2 paramètres et traite ces informations.
2cd exemple de formulaire : login Algorithme à mettre en place err '' Si (la page est appelée avec des paramètres) ALORS Si authentification correcte ALORS redirection vers accueil.html Sinon err "erreur" Fin si Fin si Afficher le code HTML de la page Si (err n'est pas vide) ALORS Afficher err Fin SI
2cd exemple de formulaire : login Script de la page <?php // C O N S T A N T E S et V A R I A B L E S define ("NOM","prof"); define ("MDP","iut"); $err=""; // V E R I F I C A T I O N du F O R M U L A I R E if (!empty($_post)) { if ($_POST['username'] == NOM && $_POST['userpwd'] == MDP) { header('location: accueil.html'); exit(); } else $err="identification incorrecte : RECOMMENCEZ!!!!!!!!!"; }?> <body> <?php if (!empty($err)) echo "<div class=\"err\">$err</div>";?> <form action="formulaire3.php" method="post"> <p><label> Nom : </label><input type="text" name="username" /></p> <p><label> Mot de passe : </label><input name="userpwd" type="password" /></p> <input type="submit" value="ok" /> </form>
Commentaires sur la page de login La page est structurée : déclaration des constantes et variables, traitement des données et présentation des données. C'est une bonne pratique à adopter en programmation. On traite toujours les informations avant de les présenter. Avec cette méthode, nous pourrons par exemple effectuer des redirections sans risque d'erreur d'en-têtes déjà envoyés. Voici quelques explications : 1 variable globale à la page est créée : $err pour le message d'erreur pour un login incorrect La première condition vérifie que le tableau $_POST existe et n'est pas vide. Si c'est le cas, alors elle renverra vrai (TRUE) [ce qui signifie que c'est le premier appel de la page] et sera franchie pour accéder aux tests suivants. On effectue ensuite une série de tests pour contrôler le login (correspondance avec les constantes définies en-tête du fichier). Si le login est correct alors la variable $message est renseignée sinon c'est la variable $err qui est renseignée. Dans le corps de la page, nous vérifierons si la variable $message existe. Si c'est le cas, on l'affiche sinon c'est le reste du code HTML qui est présenté (avec éventuellement l'indication d'erreur de login).
Traitement des contrôles de formulaire Groupe de bouton radio utilisé pour sélectionner un choix et un seul parmi plusieurs. Au maximum, un seul radio-bouton reste coché. Si l'option "checked" est ajoutée, le radio-bouton sera pré-coché. Sexe : <input name="sexe" type="radio" value="m" checked="checked" /> Masculin <input name="sexe" type="radio" value="f" /> Féminin <input name="sexe" type="radio" value="?" /> Ne sait pas ici $_POST['sexe'] ='M' Case à cocher utilisées pour des valeurs de type "oui" (case cochée) ou "non" (case décochée) si l'option "checked" est ajoutée, la case sera pré-cochée. Couleur : <input type="checkbox" name="couleur[bleu]" checked="checked" /> Bleu <input type="checkbox" name="couleur[blanc]" /> blanc <input type="checkbox" name="couleur[rouge]" /> rouge <input type="checkbox" name="couleur[nsp]" /> ne sait pas $_POST['couleur']['bleu']='on', $_POST['couleur']['rouge']='on'
Traitement des contrôles de formulaire Liste à sélection simple utilisée pour afficher une liste de valeurs qui se déroule quand on clique sur la flèche <label>langue : </label> <select name="langue"> <option value="f">français</option> <option value="a">anglais </option> <option value="c">chinois </option> </select> $_POST['langue'] ='F' Liste à sélection multiple Comme une liste simple mais avec l'attribut multiple <label>j'aime : </label><br> <select name="fruits[]" size="5" multiple> <option value="abricot">les abricots <option value="peche">les péches <option value="poire">les poires <option value="pomme">les pommes </select> $_POST['fruits'][0]='peche' $_POST['fruits'][1]='poire'
Problèmes de saisie des données Construisons un petit formulaire simple <?php $saisie =isset($_post['valeur'])?$_post['valeur']:null;?> <head> <title>essai de saisie de données</title> </head> <body> <form method="post"> <p>saisie :</p> <input name="valeur" type="text" value="<?php echo $saisie;?>"> <br><input name="" type="submit" value="ok" /> </form> <?php echo $saisie;?> </body> </html> Résultat du source de la page dans le navigateur : <body> <form method="post"> <p>saisie :</p> <input name="valeur" type="text" value="super \'cochon\'"> <br><input name="" type="submit" value="ok" /> </form> super \'cochon\' </body> Saisissons à l écran : Dépend de la configuration du serveur [php.ini paramètre magic_quotes_gpc] Ici, le système ajoute automatiquement un anti slash (\) devant les caractères apostrophe ('), guillemet (") et anti slash (\). Cette fonctionnalité se nomme magic_quote ; elle est fixée par un paramètre dans le fichier de configuration du serveur php.ini.
Une solution pour le magic_quote Le principe d'encodage magic_quote est intéressant si les données sont destinées à être enregistrées dans une base de données. En SQL, le délimiteur de chaîne est l'apostrophe. La présence d'une quote dans les écritures SQL peut produire des confusions. ( message d'erreur). L'encodage magic_quote permet d'ajouter le caractère magique (d'échappement) : caractère \. La base reçoit alors " super \' cochon\' " ce qui est CORRECT. La fonction stripslashes(chaine) supprime les anti-slash d'une chaîne La fonction get_magic_quotes_gpc() retourne 1 si l'encodage magic_quote est actif D'où la correction : $saisie=isset($_post['valeur'])?$_post['valeur']:null; if (get_magic_quotes_gpc()) { $saisie=stripslashes($saisie); }
Problèmes : les guillemets Avec le formulaire précédent, saisissons maintenant : Résultat du source de la page dans le navigateur : <body> <form method="post"> <p>saisie :</p> <input name="valeur" type="text" value="super "cochon""> <br> <input name="" type="submit" value="ok" /> </form> super "cochon" </body> Le délimiteur de chaîne en HTML est le guillemet et la séquence se termine après le guillemet de super ", le reste de la chaîne est ignoré
solution : les guillemets La fonction htmlspecialchar(chaine) prend la chaîne de caractères et converti tous les caractères spéciaux par leur équivalent HTML Les remplacements effectués sont : "&" (et commercial) devient "&" """ (guillemets doubles) devient """. "'" (guillemet simple) devient "'" "<" (inférieur à) devient "<" ">" (supérieur à) devient ">" D où la correction : <input name="valeur" type="text" value="<?php echo htmlspecialchars($saisie);?>">
Problèmes : injection de script Avec une nouvelle saisie très malicieuse : Le javascript saisi par le client est exécuté ce n'est pas souhaitable!!! La fonction strip_tags(chaine) prend la chaîne de caractères et la retourne après avoir supprimé toutes les balises HTML qu'elle contenait D où la correction : <p>saisie :</p> <input name="valeur" type="text" value="<?php echo htmlspecialchars($saisie);?>"> <br><input name="" type="submit" value="ok" /> </form> <?php echo strip_tags($saisie);?>
injection de script JS La faille de sécurité de type XSS (cross-site scripting ) http://fr.wikipedia.org/wiki/cross-site_scripting http://venom630.free.fr/geo/tutz/securite_informatique/xss/#03 Un dernier pour la route On va saisir le code suivant : <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function() { var html = '<img src="http://lorempixel.com/600/400" />' + '<p>et encore, là c\'est la version sympathique!!!'; console.log(' start ', html); $('body').append(html); }); </script>