Php $get $post $session
Introduction
Les concepts
Lorsque l'on conçoit une application Web, il y a un moment ou on est obligé de communiquer des informations entre les différentes pages de cette application. Les pages sont demandées par la partie cliente, généralement un navigateur (eg. Firefox, Chrome, Safari, ...), et sont distribuées par la partie serveur (eg. Apache HTTPd, Nginx, IIS, ...).
Cette échange est encadré par l'utilisation du protocole HTTP et doit donc utiliser des méthodes HTTP, aussi appellées verbes HTTP, consacrés :
- GET;
- POST;
- PUT;
- DELETE;
Les deux premiers sont utilisés dans les applications Web au travers de formulaires et les deux derniers sont plutôt utilisés dans le cadre de Web services RESTful.
On distingue donc deux cas de figure :
- l'envoie d'informations du client au serveur;
- la conservation d'information côté serveur.
Dans le premier cas de figure, on peut utiliser les méthodes GET ou POST, alors que dans le deuxième cas de figure on utilisera les sessions.
Création d'un projet
Pour illustrer ces propos nous allons créer un projet dans Eclipse et pour cela assurez-vous d'avoir la perspective Php ainsi que d'avoir suivi le tutoriel Xdebug.
Commençons par la création du projet:
- Première écran de l'assistant :
- on créé le projet sur le serveur local;
- on active le support de JavaScript
- Deuxième écran de l'assistant :
- On créé un repertoire src
- On clique sur finish pour terminer l'assistant
Une fois le projet créé, on va y ajouter une page index.php
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Formulaire</title>
</head>
<body>
<div align="center">
<form action="php/traitement.php" method="get">
Login :
<input type="text" name="login"><br>
Password :
<input type="password" name="password"><br>
<input type="submit" value="Connexion">
</form>
</div>
</body>
</html>
Comme vous pouvez le constater, cette page ne contient pas le code Php en charge du traitement du formulaire. Elle envoie les informations à la page traitement.php qui se trouve dans le répertoire php. Voici le code de cette page :
<?php
var_dump($_GET);
La méthode GET
Pour l'instant, en phase de découverte, nous allons utiliser la fonction var_dump qui permet d'afficher le contenu d'une variable, peu importe son type. On pourrait également utiliser la vue Debug d'Eclipse pour voir le contenu de la variable en mémoire. Peu importe la solution retenue, l'important et de voir la corrélation entre :
- les données du formulaire;
- l'URL;
- le tableau $_GET créé par l'interpréteur Php.
Envoie d'information
Lorsque l'on valide le formulaire, le navigateur va construivre l'URL suivante :
http://localhost/Form/src/php/traitement.php?login=toto&password=titi
Et l'interpréteur Php va remplir le tableau $_GET de la manière suivante (résultat du var_dump) :
array (size=2) 'login' => string 'toto' (length=4) 'password' => string 'titi' (length=4)
On peut s'amuser à modifier les valeurs dans l'URL pour comprendre l'impact sur le contenu du tableau $_GET : l'interpréteur construit un tableau associatif ou figurera chacun des tuples présent dans l'URL. Le caractère ? sert à séparer la ressource demandée de la liste des tuples et le caractère & sert à séparer chacun des tuples dans la liste.
Réception d'information
La récupération d'une valeur semble simple : il suffit d'y accéder en spécifiant son nom.
<?php
$login = $_GET["login"];
$password = $_GET["password"];
echo "Votre login est : ".$login;
echo "<br>";
echo "Votre mot de passe est : ".$password;
La méthode POST
Envoie d'information
Très similaire à la méthode GET à la différence que les tuples sont envoyé dans le corps de la requête HTTP et non dans l'URL. Pour l'utiliser, il suffit de modifier la ligne suivante du fichier index.php :
<form action="php/traitement.php" method="get">
en
<form action="php/traitement.php" method="post">
Réception d'information
La récupération des informations ce fait non plus dans le tableau $_GET mais dans le tableau $_POST :
<?php
$login = $_POST["login"];
$password = $_POST["password"];
echo "Votre login est : ".$login;
echo "<br>";
echo "Votre mot de passe est : ".$password;
Limitations
Une variable manque à l'appel !
Que se passe t-il si l'un des paramètres manque ? Si, par exemple, il manque le tuple password comme c'est le cas avec l'URL suivante:
http://localhost/Form/src/php/traitement.php?login=toto
Ci-dessous un extrait du fichier /var/log/httpd/error_log
[Mon Jun 27 04:49:56 2016] [error] [client 192.168.100.1] PHP Notice: Undefined index: password in /var/www/html/Form/src/php/traitement.php on line 4 [Mon Jun 27 04:49:56 2016] [error] [client 192.168.100.1] PHP Stack trace: [Mon Jun 27 04:49:56 2016] [error] [client 192.168.100.1] PHP 1. {main}() /var/www/html/Form/src/php/traitement.php:0
Pour ne pas prendre de risque il faudrait tester si l'index existe en utilisant la fonction isset :
<?php
if (isset ( $_GET ["login"] )) {
$login = $_GET ["login"];
echo "Votre login est : " . $login;
echo "<br>";
}
if (isset ( $_GET ["password"] )) {
$password = $_GET ["password"];
echo "Votre mot de passe est : " . $password;
}
Ma variable est vide !
Que se passe t-il si la variable est vide ? Si, par exemple, le tuple password ne possède pas de valeur comme c'est le cas avec l'URL suivante:
http://localhost/Form/src/php/traitement.php?login=toto&password
Aucune erreur n'est générée mais le reste du code risque de ne pas fonctionner correctement... Il faudrait tester si la variable n'est pas vide grâce à la fonction empty
if (isset ( $_GET ["login"] )) {
$login = $_GET ["login"];
if (! empty ( $login )) {
echo "Votre login est : " . $login;
echo "<br>";
}
}
if (isset ( $_GET ["password"] )) {
$password = $_GET ["password"];
if (! empty ( $password )) {
echo "Votre mot de passe est : " . $password;
}
}
Réfléxion...
Pour ce formulaire composé de seulement deux champs on constate que la quantité de code qu'il faut écrire, si on veut faire un traitement efficace des valeur, est colossale. On imagine facilement que plus il y aura de champs plus cela sera pénible...
Il faudrait un moyen, pas trop compliqué, de savoir si une variable existe et si elle à une valeur.
Nous allons écrire deux fonctions pour cela dans le fichier php/helper.php :
<?php
function getVar($name) {
if (isset ( $_GET [$name] )) {
if (! empty ( $_GET [$name] )) {
return $_GET [$name];
}
return TRUE;
}
return FALSE;
}
function postVar($name) {
if (isset ( $_POST [$name] )) {
if (! empty ( $_POST[$name] )) {
return $_POST[$name];
}
return TRUE;
}
return FALSE;
}
Ces fonctions renvoies :
- faux si la variable n'existe pas ;
- vrai si elle existe mais est vide ;
- sinon sa valeur.
La philosophie est simple:
- soit on à besoin que la variable existe et on fait le test suivant :
$var = getVar("var");
// Si différent de faux, la variable existe avec une valeur ou non !
if($var !== FALSE){
...
}
- soit il faut absolument une valeur et on fait le test suivant :
$var = getVar("var");
// Si la variable n'est pas un booleen, elle à une valeur !
if(!is_bool($var)){
...
}
Voyez comme le code est plus clair, simple, efficace :
<?php
include 'helper.php';
$login = getVar ( "login" );
$password = getVar ( "password" );
if (! is_bool ( $login )) {
echo "Votre login est : " . $login;
echo "<br>";
}
if (! is_bool ( $password )) {
echo "Votre mot de passe est : " . $password;
}
Interaction
Redirection après vérification
Il faudrait maintenant tester les valeurs des champs pour confirmer ou infirmer l'authentification. Pour ce faire, nous allons modifier la page traitement.php:
<?php
include 'helper.php';
// Valeur par défaut
$stored_login = "root";
$stored_password = "toor";
$login = getVar ( "login" );
$password = getVar ( "password" );
if (! is_bool ( $login ) && ! is_bool ( $password )) {
if($login == $stored_login && $password == $stored_password){
// Authentification réussie
return header("Location: ../logged.php");
}
}
// Authentification échoué
header("Location: ../index.php");
Dans ce script :
- on définit au début les valeurs du couple login / mot de passe mais on aurait pu récupérer ces valeur dans une base de données;
- on utilise la fonction header avec la valeur Location qui permet de rediriger le navigateur en ajoutant un header HTTP à la réponse.
Si l'authentification se passe correctement, on est redirigé vers la page logged.php (que nous allons créer), si elle échoue on revient sur la page index.php pour faire une nouvelle tentative de connexion. Voici le code de la page logged.php:
<?php
echo "Authentification réussie !";
User eXperience
En UX, on s'intéresse beaucoup à l'utilisateur et son ressenti. Que va t-il se passer si l'authentification échoue ? Il sera redirigé tellement vite sur la page index.php qu'il aura l'impression que rien ne s'est passé... Il faut absolument que la page index.php affiche un message qui informe de l'échec de l'authentification !
C'est traitement.php qui détient l'information de l’échec ou de la réussite de l'authentification... Il faudrait que cette page transmette l'information à index.php ! Comment faire... avec un GET mais, cette fois, sans formulaire et uniquement en modifiant l'URL de redirection en cas d'échec. Dans le fichier traitement.php modifiez la ligne suivante :
<?php
// Authentification échoué
header("Location: ../index.php");
en
<?php
// Authentification échoué
header("Location: ../index.php?echec");
Il suffit maintenant de récupérer l'information dans la page index.php. Ajouter, au dessus de la div existante, le code suivant :
<div align="center">
<?php
include 'php/helper.php';
$echec = getVar("echec");
if($echec !== FALSE){
echo "Echec de l'authentification !";
}
?>
</div>
Lorsque l'on échoue l'authentification, un message s'affiche !