Le problème
On veut pouvoir conserver des informations d’une page sur l’autre, comme l’identifiant de l’utilisateur connecté (pour ne pas avoir à se reconnecter à chaque page), tout en empêchant autant que possible l’usurpation d’identité.
Dans les exemples présentés ici, on se limitera à transmettre le contenu d’une variable, nommée $test
, d’une exécution à l’autre d’un même script, en précisant quand et comment un utilisateur a la possibilité de modifier cette valeur.
La variable
Une variable n’est conservée que pendant l’exécution courante d’un script. Si on charge un autre script, ou même si on recharge le script courant, le contenu des variables est perdu :
<?php
if(! isSet($test))
$test = "toto";
?>
<!DOCTYPE html>
<html dir="ltr" xml:lang="fr-FR" lang="fr-FR">
<head>
<meta charset="utf8" />
<title>Test variable</title>
<meta name="author" content="Christophe Prieur" />
</head>
<body>
<?php
echo "<p>$test</p>";
$test = "tutu";
echo "<p>$test</p>";
?>
<p>Rechargez la page pour voir si la valeur de la variable est conservée</p>
</body>
</html>
Résultat ici.
GET
On peut alors transmettre le contenu d’une variable comme paramètre du script :
<?php
if(isSet($_GET["test"]))
$test = htmlentities($_GET["test"]);
else
$test = "toto";
?>
<!DOCTYPE html>
<html dir="ltr" xml:lang="fr-FR" lang="fr-FR">
<head>
<meta charset="utf8" />
<title>Test get</title>
<meta name="author" content="Christophe Prieur" />
</head>
<body>
<?php
echo "<p>$test</p>";
$test = "tutu";
echo "<p>$test</p>";
?>
<p>
<?php
echo "<a href=\"?test=$test\">";
echo "Recharger en conservant la valeur</a>.";
?>
</p>
</body>
</html>
Résultat ici.
La méthode get est faite pour que l’utilisateur puisse changer facilement le paramètre (comme dans le cas d’une requête à un moteur de recherche par exemple), en le tapant directement dans la barre d’adresse. Par conséquent,
on a utilisé ici htmlentities
pour « neutraliser » les éventuels caractères spéciaux qui permettraient à l’utilisateur d’envoyer du code html, d’autant qu’on affiche la valeur transmise.
Exemple de tentative d’affichage d’une image :
qui se solde par un échec, grâce à htmlentities
:
Si on veut empêcher l’utilisateur de fixer lui-même la valeur de la variable, on doit utiliser une autre méthode.
POST
Avec la méthode post, le paramètre ne passe pas par l’url :
<?php
if(isSet($_POST["test"]))
$test = htmlentities($_POST["test"]);
else
$test = "toto";
?>
<!DOCTYPE html>
<html dir="ltr" xml:lang="fr-FR" lang="fr-FR">
<head>
<meta charset="utf8" />
<title>Test get</title>
<meta name="author" content="Christophe Prieur" />
</head>
<body>
<?php
echo "<p>$test</p>";
$test = "tutu";
echo "<p>$test</p>";
?>
<p>
<form action="" method="post">
<?php
echo '<input type="hidden" name="test" value="'
. $test . '" />';
?>
<input type="submit" value="Recharger en conservant la valeur" />
</form>
</p>
</body>
</html>
Résultat ici.
La modification de la variable n’est donc plus à la portée de n’importe quel utilisateur comme c’est le cas avec get, mais elle reste néanmoins triviale pour un développeur web, puisqu’il suffit de répliquer le formulaire dans n’importe quel script php en indiquant l’adresse du script ci-dessus :
<html dir="ltr" xml:lang="fr-FR" lang="fr-FR">
<head>
<meta charset="utf8" />
<title>Test post</title>
<meta name="author" content="Christophe Prieur" />
</head>
<body>
<p>
<form action="param-post.php" method="post">
<input type="hidden" name="test" value="je suis un tricheur">
<input type="submit" value="Charger avec ma valeur" />
</form>
</p>
</body>
</html>
Résultat ici.
Cette méthode permet donc de transmette des paramètres dont on ne souhaite pas que le contenu ou le nom soient immédiatement visibles, mais ici encore,
si on veut empêcher l’utilisateur de fixer lui-même la valeur de la variable, on doit utiliser une autre méthode.
Les cookies
Les cookies sont des informations stockées sur le client (donc le navigateur) à la demande du serveur.
Pour placer un cookie sur le client, on utilise la fonction setcookie
:
setcookie(paramètre, valeur)
setcookie(paramètre, valeur, time() + s)
, pour fixer une durée de vie s en secondes.
Attention La fonction setcookie
doit être appelée avant tout affichage, sinon elle se solde par un échec. En particulier, il ne doit y avoir aucun caractère (même un espace ou un saut de ligne) entre le début du fichier et la balise php.
On récupère les valeurs des paramètres au moyen de $_COOKIE[paramètre]
ou de $_REQUEST[paramètre]
(ce dernier permet également de récupérer un paramètre transmis par get ou post). Ces variables ne peuvent être utilisées qu’un lecture (pour modifier la valeur de $_COOKIE
, il faut utiliser la fonction setcookie
).
<?php
if(isSet($_COOKIE["test"]))
$test = htmlentities($_COOKIE["test"]);
else
$test = "toto";
$newtest = "tutu";
$res = setcookie("test", $newtest, time() + 300);
?>
<!DOCTYPE html>
<html dir="ltr" lang="fr-FR">
<head>
<meta charset="utf8" />
<title>Test cookie</title>
<meta name="author" content="Christophe Prieur" />
</head>
<body>
<?php
echo "<p>$test</p>";
$test = $newtest;
echo "<p>$test</p>";
?>
<p>
<?php
if($res)
echo "Le cookie a bien été envoyé, rechargez la page pour tester.";
else
echo "Le cookie n'a pas pu être envoyé, laissez-moi tranquille !";
?>
</p>
</body>
</html>
Résultat ici. La durée de vie du cookie a été mise à 5 minutes (300 secondes) pour permettre des tests.
Les cookies sont utilisés notamment pour stocker des informations sur la navigation de l’utilisateur (préférences) sans qu’il soit identifié. Comme ils sont stockés par le navigateur, sur le disque de l’utilisateur, il lui est toujours possible d’y accéder, de les afficher, voire de les modifier (au moyen d’extensions Firefox, Chrome ou Opera).
Par conséquent, ici encore, si on veut vraiment empêcher l’utilisateur de fixer lui-même la valeur de la variable, on doit utiliser une autre méthode.
Les sessions
C’est un mécanisme de php pour stocker des informations sur le serveur entre deux visites d’un même utilisateur en limitant l’information transmise par le client à une seule valeur, l’identifiant de session, générée au moyen d’un procédé cryptographique qui rend extrêmement difficile sa falsification.
L’identifiant de session est transmis sans même que le programmeur n’ait à s’en soucier, au moyen d’un cookie, ou de la méthode get si le navigateur est configuré pour ne pas accepter les cookies.
Pour démarrer une session ou reprendre une session existante, on utilise la fonction session_start
(sans paramètres), qui renvoie un booléen indiquant si l’opération a réussi.
On fixe ensuite les valeurs des paramètres que l’on souhaite au moyen de $_SESSION[paramètre]
, qui peut être utilisé en lecture comme en écriture (contrairement à $_COOKIE
, $_REQUEST
, $_GET
et $_POST
, qui ne s’utilisent qu’en lecture).
Attention Comme pour setcookie
, la fonction session_start
doit être appelée avant tout affichage, sinon elle se solde par un échec. En particulier, il ne doit y avoir aucun caractère (même un espace ou un saut de ligne) entre le début du fichier et la balise php.
<?php
$res = session_start();
if(isSet($_SESSION["test"]))
$test = htmlentities($_SESSION["test"]);
else
$test = "toto";
$newtest = "tutu";
?>
<!DOCTYPE html>
<html dir="ltr" lang="fr-FR">
<head>
<meta charset="utf8" />
<title>Test session</title>
<meta name="author" content="Christophe Prieur" />
</head>
<body>
<?php
echo "<p>$test</p>";
$_SESSION["test"] = $test = $newtest;
echo "<p>$test</p>";
?>
<p>
<?php
if($res)
echo "La session a bien été créée, rechargez la page pour tester.";
else
echo "La session n'a pas pu être créée, laissez-moi tranquille !";
?>
</p>
</body>
</html>
Résultat ici.
Pour fermer la session, on utilise session_destroy
(sans paramètres),
qui renvoie un booléen indiquant si l’opération a réussi.
Pour plus de détails sur les sessions php, consulter la documentation php sur la gestion des sessions