[Plan du site]
Vous êtes ici ---
> Le Site du Zér0
> Les tutoriels
> Non-Officiels
> Site Web
> PHP
> Points particuliers
> Lecture du tutoriel
Supprimer le message qui renvoie les données contenues par POST
Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Bonjour à tous.
Pour lire ce tuto, il est fortement conseillé d'avoir lu les trois premières parties du tuto de M@teo21 sur le PHP. Vous pouvez essayer sans, mais vous aurez certainement beaucoup de mal.
Ici, nous apprendrons à supprimer le message qui vous traque, celui qui vous menace, celui qui vous ennuie, celui qui vous nargue, celui sur lequel vous avez passé des jours et des nuits de travail sans résultats satisfaisants, celui qui vous fais suer, celui qui n'a pas de pitié ... Lui !
Ce message, celui qui vous tue, n'est autre qu'une erreur affichée par votre navigateur.
Mais attendez un peu avant de massacrer votre navigateur, il n'y est
presque pour rien dans l'histoire.

En fait, il est même très gentil, car il vous prévient que la
"super-globale POST" va renvoyer les données qu'elle contient.
C'est un peu plus compliqué que ça, mais chaque chose à la fois.
Mais en fait, c'est quoi "la super-globale POST" ?
Bonne question.

Tout d'abord, une super-globale, c'est quoi ? En PHP, vous ne pouvez pas échapper aux super-globales. Vous en avez sûrement déjà utilisé, même si vous ne saviez pas ce que c'était. Les super-globales sont des variables (plus précisément, des
array) qui vont récupérer les données d'un formulaire ou bien d'informations qui passent par les URL, par les sessions, ou même par les cookies.
La "super-globale
POST", c'est la variable qui va récupérer les données des formulaires.
Un petit point sur l'historique et le fonctionnement des super-globales.
Je voudrais d'abord vous sensibiliser sur un point important avec les super-globales, un problème de sécurité qui peut aussi bien être inoffensif qu'extrêmement problématique.
Avant la version 4.2.0 de PHP, on pouvait récupérer les données d'un formulaire comme ceci :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | <?
// Le formulaire
echo '<form action="mapage.php" method="post">' ;
echo '<label for="texte">Texte : </label> <input type="text" name="texte" id="texte" /><br />' ;
echo '<input type="submit" value="Poster !" />' ;
echo '</form>' ;
// Le traitement du formulaire
if(isset($texte))
{
echo '<br />' ;
echo 'Vous avez envoyé le formulaire !' ;
}
?>
|
Mais on pouvait aussi récupérer les informations envoyées via les URL de la même façon, tout comme avec les sessions, et les cookies. Donc, si on allait sur la page
mapage.php?texte=1, on voyait le message
"Vous avez envoyé le formulaire !", alors qu'on avait rien envoyé du tout !
Et en tant que Zéro, vous devez être bien intrigué par ce code. En effet, j'ai récupéré l'entrée du formulaire
texte par la variable
$texte, alors que jusqu'à présent, vous aviez l'habitude de faire :
$_POST['texte'].
Eh oui, avant on pouvait les récupérer comme ceci, car la directive PHP
register_globals était
"On".
Houlà

C'est quoi ça, la direction de PHP enregistrée globale, ou je sais plus trop quoi ?
La directive PHP register_globals est un paramètre de php qui était activé de sorte à ce que l'on puisse récupérer des données de formulaires, d'URL, de sessions ou de cookies via de simples variables.
Mais on s'est rendu compte que c'était tout de même un problème assez important au niveau de la sécurité des scripts. Depuis la version 4.2.0 de php, on a donc décidé de passer ce paramètre à
"Off". Et depuis ce temps, nous sommes obligés de récupérer les données des formulaires via la super-globale
$_POST, les informations contenues dans les URL via la super-globale
$_GET, etc.
Tout ceci est bien pratique, car on sait d'où viennent nos variables, et on ne peut plus confondre des variables venant des URL avec des variables venant des formulaires.
Le hic, c'est que pour beaucoup d'hébergeur, ce paramètre est mis à
"On". Pour savoir quelle est la valeur de
register_globals sur votre hébergeur, il faut vous renseigner via la fonction
phpinfo(). Pour l'utiliser, il suffit simplement de faire ceci sur une page vierge :
Code : PHP
Vous faites CTRL + F ( rechercher ), vous tapez
register_globals, et vous regardez sa valeur.
Si elle est
"On", alors il faudra faire attention à ne pas s'emmêler dans vos noms de variables, si elle est à
"Off", alors c'est parfait.
Si vous souhaitez en savoir plus sur les super-globales, je vous invite à lire deux chapitres sur php.net, que je trouve très bien

:
Lors de l'envoie d'un formulaire ...
C'est bien beau tout ça, mais moi je suis ici pour supprimer le message !
Allez, crache le morceau, dis comment tu fais !

Messieurs, un peu de patience je vous prie !

Avant de supprimer le message, il vous reste quelque chose à savoir :
Que ce passe-t-il lors de l'envoie d'un formulaire ?
Car oui, le message apparaît suite à l'envoie d'un formulaire, ce qui veut dire que l'erreur à régler provient du formulaire, non ?
Alors, que se passe-t-il de si spécial ? Comment nos données sont récupérées ?
Tout ça se résume en quatre mots :
La mise en cache.
Explications :
Lorsqu'on envoie un formulaire, les données que vous avez entrées sont mises en cache, c'est à dire qu'elles sont enregistrées.
Ensuite, PHP les récupère et travaille avec.
L'ennuie, c'est que si on n'efface pas ces données, votre navigateur va afficher un message pour dire qu'elles sont toujours dans le cache, et qu'elles vont être étudiées et travaillées par PHP une nouvelle fois.
Avant d'appliquer la méthode magique qui permet de supprimer le message, il faudrait que vous compreniez comment elle fonctionne, ainsi pourquoi et comment on l'a choisie.
On sait que le message apparaît pour nous prévenir que les données qui sont dans le cache vont être retravaillées. La question qu'il faut se poser, c'est :
Comment les retirer du cache ?
Pour les retirer, il n'y a pas trente six solutions : Le rafraîchissement de la page.
Sauf qu'il y a un léger problème : Quand on rafraîchit, les données sont encore dans le cache, donc on va avoir le message d'erreur.
On devra alors se débrouiller pour rafraîchir la page nous-mêmes, comme ça le message n'apparaîtra pas.

Et pour rafraîchir une page automatiquement, il n'y a pas non plus une centaine de possibilités : La redirection.
Des façons pour rediriger, il y en a en HTML, en JavaScript et évidemment en PHP. Mais avant de vous lancer tout de suite dans la redirection en PHP, j'aimerais vous parler de celles en HTML et en JavaScript.
Alors quoi ? Tu nous dis que ça fait des jours et des jours que nous cherchons une technique pour supprimer ce message et que cette technique, elle se résume à une fonction ?

Traître ! Tu aurais pu nous le dire plus tôt ! À l'assaaaaaaaaaaut

Mais non, mais non, voyons, je n'ai rien fait, moi.

Enfin, il y a un peu de vrai là-dedans. Cette technique est très simple quand on veut s'y mettre, mais il y a un petit inconvénient qui va nous obliger à utiliser une technique spéciale :
Comme on vide les données du cache, il faudra les traiter avant de rediriger.
Allez, ça fait bien longtemps qu'on papote, alors autant passer à la pratique maintenant.
Révisons ce que nous savons pour le moment :
- Pour supprimer le message, il faut utiliser une redirection en php, via la fonction header.
- Mais cette fonction, il faut l'utiliser avant tout code HTML.
- Mais comme la redirection va vider les données sur lesquelles on travaille, il va falloir les traiter avant de rediriger.
Donc, si on doit traiter le formulaire avant la fonction
header, et que cette fonction doit être utilisée avant tout code HTML, il faudra donc traiter le formulaire avant d'afficher la page.
Un petit script pour résumer tout ça, histoire que ça soit bien clair dans vos esprits ?
Regardez bien la structure, elle est très importante. Et si vous pensez que vous n'êtes pas prêt, ou que j'ai été un peu trop vite, n'hésitez pas à stopper votre lecture ici et relire le début du tuto.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 | <?
mysql_connect('localhost', 'root', '');
mysql_select_db('test');
// Connexion à MySQL
// Petite fonction pour soulager les codes.
function formulaire($str)
{
return mysql_real_escape_string(htmlentities($str));
}
// On traîte bien le formulaire avant d'afficher la page.
if(isset($_POST['formulaire'])) // Si on a lancé le formulaire.
{
$pseudo = trim($_POST['pseudo']);
$message = trim($_POST['message']);
// Si on a rempli correctement tous les champs.
if(isset($pseudo, $message) AND !empty($pseudo) AND !empty($message))
{
// Si le pseudo fait bien moins de 15 caractères.
if(strlen($pseudo) < 15)
{
// Si le message fait bien moins de 200 caractères.
if(strlen($message) < 200)
{
$pseudo = formulaire($pseudo);
$message = formulaire($message);
mysql_query('INSERT INTO chat VALUES("", '. time() . ', "'. $pseudo .'", "'. $message .'")') OR die(mysql_error());
}
}
}
// On redirige pour vider le cache et supprimer le message.
header('Location: test.php');
}
// On commence à afficher la page.
echo '<html>' ;
echo '<body>' ;
echo '<form action="test.php" method="post">' ;
echo '<label for="pseudo">Pseudo : </label> <input type="text" name="pseudo" id="pseudo" maxlength="15" /><br />' ;
echo '<label for="message">Message : </label> <input type="text" name="message" id="message" maxlength="200" /><br />' ;
echo '<input type="hidden" name="formulaire" value="1" />' ;
echo '<input type="submit" value="Envoyer !" />' ;
echo '</form>' ;
// On affiche les messages de la table.
$reponse = mysql_query('SELECT * FROM chat');
while($donnees = mysql_fetch_array($reponse))
{
echo '<strong>De ' . stripslashes($donnees['pseudo']) . ', le ' . date('d/m/Y à H:i:s', $donnees['time']) . '</strong><br />' ;
echo nl2br(stripslashes($donnees['message'])) . '<br /><br />' ;
}
echo '</body>' ;
echo '</html>' ;
?>
|
Peut-être que cette histoire de traitement du formulaire avant l'affichage de la page était un peu floue dans votre esprit, ou autre chose, enfin bref : c'est de cette manière que vous devrez faire vos scripts maintenant. Regardez-le bien, il est très important.
C'est surtout la structure qu'il faut retenir :
- 1. Traitement du formulaire :
- On fait les conditions qu'il faut, pour vérifier les données envoyées.
- On redirige pour retirer les données du formulaire qui étaient dans le cache.
- 2. On affiche la page.
Hep là ! Tout ça c'est bien joli, mais comment je fais pour dire à mon visiteur que son formulaire n'est pas valide ? Si je redirige, je peux plus marquer de texte avant moi !

Exact.

Pour résoudre ce problème, nous allons nous poser une petite suite de questions logiques, ce qui nous permettra de résoudre notre problème.
La question est :
Comment dire à la page affichant les erreurs d'écrire la bonne erreur ?
En premier lieu, il faudrait dire à la page qu'il y a une erreur à afficher. Pour ça, on pourrait laisser un chiffre dans l'URL lors de la redirection, pour dire à la page suivante qu'il y a des erreurs attendant d'être affichées.
Code : PHP1
2
3 | <?
header('Location: mapage.php?erreur=1');
?>
|
Et ensuite on fait une petite condition qui dit que si
$_GET['erreur'] == 1, on affiche une erreur.
Voilà un problème de résolu !
C'est bien mignon, mais j'affiche quelle erreur avec ça moi ?
Chaque chose en son temps.

Pour dire quelle erreur afficher, on pourrait mettre le texte de celle-ci directement dans l'URL, comme ceci :
Code : PHP1
2
3 | <?
header('Location: mapage.php?erreur=Vous n\'avez pas saisi le formulaire correctement !');
?>
|
Mais ça ne fait franchement pas
"pro" du tout, et le visiteur pourrait changer l'erreur.
On pourrait alors laisser un numéro dans l'URL, qui correspondrait à une erreur précise, comme ceci :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | <?
if(isset($_POST['formulaire']))
{
if(isset($_POST['badaboum']))
{
$erreur = 1 ;
}
else
{
$erreur = 2 ;
}
header('Location: mapage.php?erreur=' . $erreur);
}
?>
|
Et lors de l'affichage, on affiche l'erreur correspondant au numéro, via un
array pour faire plus simple, comme ceci :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13 | <?
if(isset($_GET['erreur']))
{
$erreurs = array('', 'Vous connaissez monsieur Badaboum ?!', 'Vous ne connaissez même pas monsieur Badaboum ! o_O') ;
/* On vérifie si le numéro qui est dans l'URL correspond à une erreur.
Autrement dit, on vérifie si le numéro n'a pas été truqué. */
if(array_key_exists($_GET['erreur'], $erreurs))
{
echo '<strong>' . stripslashes($erreurs[$_GET['erreur']]) . '</strong>' ;
}
}
?>
|
Mais le visiteur pourrait changer le numéro qui est dans l'URL, pour afficher une autre erreur.
Il faudrait alors se débrouiller pour savoir si l'erreur qu'on affiche est bien directement suite au traitement de notre formulaire. Grâce à ça, on n'affichera l'erreur que si elle est suite à la redirection, point c'est tout. Donc si on rafraîchirait ou qu'on irait sur
mapage.php?erreur=2, on ne verrait pas l'erreur.
Pour vérifier ceci, nous allons utiliser les sessions !
Les sessions ?

Ben pourquoi pas les cookies !

L'avantage des sessions, c'est que les visiteurs ne peuvent pas les modifier, contrairement aux URL ( ou aux cookies

). De plus, les sessions sont
"invisibles".
Ok, mais pourquoi pas une variable normale ?
Une variable ne peut être utilisée que sur la page où elle est déclarée. Là, on va rediriger notre visiteur, donc on change de page (même si on ne change pas obligatoirement de fichier). Donc en redirigeant, il serait impossible de récupérer une variable normale.
Juste avant la redirection, vous allez déclarer la session
$_SESSION['redirection']. Et lors de l'affichage de l'erreur, vous vérifierez si la session existe, puis vous la supprimerez. Petit exemple pour clarifier tout ça :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | <?
session_start();
if(isset($_POST['formulaire']))
{
// Traitement du formulaire, conditions, déclaration de $erreur ...
$_SESSION['redirection'] = 1 ;
header('Location: mapage.php?erreur=' . $erreur);
}
// Si on vient tout juste d'être redirigé, et qu'il y a une erreur à afficher.
if(isset($_GET['erreur'], $_SESSION['redirection']))
{
// Traitement des erreurs
// On supprime la session
unset($_SESSION['redirection']) ;
}
// Affichage de la page, du formulaire, etc.
?>
|
Explications :
Lorsqu'on envoie le formulaire,
$_SESSION['redirection'] est déclarée, puis on redirige vers la page qui va afficher les erreurs.
Lorsqu'on affiche les erreurs, on vérifie si
$_SESSION['redirection'] existe, puis on la supprime.
De cette manière, si on rafraîchit la page, le message n'apparaît plus :
C'est ce qu'on voulait, l'erreur ne s'affiche plus qu'après le traitement du formulaire.
Vous voilà donc avec votre joli petit système qui marche parfaitement bien.
Mais, tant qu'à faire, autant l'améliorer du mieux possible, non ?
Nous avons dis tout à l'heure que les sessions étaient impossibles à modifier par les visiteurs. Pourquoi alors ne pas vous en servir pour transmettre le numéro qui permet d'afficher l'erreur ?
Ou même, j'ai mieux : Pourquoi ne pas stocker directement l'erreur dedans ? Puisqu'elles sont
"invisibles", ça fait plus
"pro", et elles ne pourront pas être modifiées par les visiteurs.
Le truc rêvé.
Dans cette dernière partie, nous allons récapituler tout ce que nous savons.
Pour vérifier vos connaissances, rien ne vaut de tel qu'un peu de pratique. Nous allons donc appliquer ce qu'on a vu depuis le début, en créant un mini-chat sans le message d'erreur qui renvoie (que dis-je, renvoy
ait 
) vos données.
Vous pouvez évidemment vous aider du script précédent, dans la partie
"Un peu de mise en pratique". D'ailleurs, je vous le recommanderais si vous êtes toujours un peu incertain.
Voici "la tête" que devra avoir votre script :
- 1. Traitement du formulaire, on stocke les messages d'erreurs directement dans une session, on redirige.
- 2. Si il y a des erreurs, on les affiche. Ce n'est plus la peine de s'embêter avec un array, vu que les messages d'erreurs sont stockés dans une session.
- 3. On affiche la page, le formulaire, etc.
Allez, maintenant, à vos claviers !
Correction
Voici maintenant la correction. Mais je dois vous dire une chose : Comparer au script précédent, il n'y a pas grand chose qui change, à part les messages d'erreurs qui sont contenus dans une session. Et ça, ce n'est franchement pas compliqué.
Alors ne regardez la correction qui si vous êtes vraiment coincé depuis plusieurs dizaines de minutes, que vous transpirez de partout et que vous allez piquer une crise de nerf.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77 | <?
mysql_connect('localhost', 'root', '');
mysql_select_db('test');
session_start();
function formulaire($str)
{
return mysql_real_escape_string(htmlentities($str));
}
if(isset($_POST['formulaire']))
{
$message = trim($_POST['message']);
$pseudo = trim($_POST['pseudo']);
if(isset($message, $pseudo) AND !empty($message) AND !empty($pseudo))
{
if(strlen($pseudo) < 15)
{
if(strlen($message) < 200)
{
$pseudo = formulaire($pseudo);
$message = formulaire($message);
mysql_query('INSERT INTO chat VALUES("", ' . time() . ', "' . $pseudo . '", "' . $message . '")') OR die(mysql_error());
$_SESSION['erreur'] = 'Message ajouté !' ;
}
else
{
$_SESSION['erreur'] = 'Le message est trop long !' ;
}
}
else
{
$_SESSION['erreur'] = 'Le pseudo est trop long !' ;
}
}
else
{
$_SESSION['erreur'] = 'Erreur de saisie des champs obligatoires !' ;
}
header('Location: test.php?h=1');
}
echo '<html>' ;
echo '<body>' ;
if(isset($_GET['h'], $_SESSION['erreur']))
{
echo '<strong>' . stripslashes($_SESSION['erreur']) . '</strong><br />' ;
unset($_SESSION['erreur']);
}
echo '<form action="test.php" method="post">' ;
echo '<label for="pseudo">Pseudo : </label> <input type="text" name="pseudo" id="pseudo" maxlength="15" /><br />' ;
echo '<label for="message">Message : </label> <input type="text" name="message" id="message" maxlength="200" /><br />' ;
echo '<input type="hidden" name="formulaire" value="1" />' ;
echo '<input type="submit" value="Envoyer !" />' ;
echo '</form>' ;
$reponse = mysql_query('SELECT * FROM chat');
while($donnees = mysql_fetch_array($reponse))
{
echo '<strong>De ' . stripslashes($donnees['pseudo']) . ', le ' . date('d/m/Y à H:i:s', $donnees['time']) . '</strong><br />' ;
echo nl2br(stripslashes($donnees['message'])) . '<br /><br />' ;
}
echo '</body>' ;
echo '</html>' ;
?>
|
Voilà, il n'y a pas grand chose à expliquer sur ce code.
Comme je l'ai plus haut, il est très semblable au précédent, et il y a juste l'histoire des messages d'erreur qui change.
Donc regardez, regardez, et regardez encore une fois, pour bien que vous compreniez comment ça fonctionne, pour que vous puissiez adopter cette technique dans vos scripts, sans que vous ayez besoin de revenir ici.
Nous voici donc à la fin de ce tuto.

J'espère que vous avez réussi à bien le comprendre, et si ce n'est pas le cas, où si vous avez des recommandations, des questions, n'hésitez pas à m'envoyer un MP ou à poster un commentaire.