Aller au menu - Aller au contenu

Icône Transmettre des données avec l'URL

Mise à jour : 03/04/2010
Difficulté : Intermédiaire Intermédiaire Creative Commons BY-NC-SA
133 390 visites depuis 7 jours, dont 3 866 sur ce chapitre classé 2/786
Savez-vous ce qu'est une URL ? Cela signifie Uniform Resource Locator, cela sert à représenter une adresse sur le web. Toutes les adresses que vous voyez en haut de votre navigateur, comme http://www.siteduzero.com, sont des URL.

Je me doute bien que vous ne passez pas votre temps à regarder ces URL (il y a bien mieux à faire !), mais je suis sûr que vous avez déjà été surpris de voir certaines URL assez longues avec des caractères un peu curieux. Par exemple, après avoir fait une recherche sur Google, la barre d'adresse contient une URL longue qui ressemble à ceci : http://www.google.fr/search?rlz=1C1GFR343&q=siteduzero. Les informations après le point d'interrogation dans cette URL sont des données que l'on fait transiter d'une page à une autre. Nous allons découvrir dans ce chapitre comment cela fonctionne.
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Envoyer des paramètres dans l'URL

En introduction, je vous disais que l'URL permettait de transmettre des informations. Comment est-ce que ça fonctionne exactement ?

Former une URL pour envoyer des paramètres



Imaginons que votre site s'appelle monsite.com et que vous avez une page PHP intitulée bonjour.php. Pour accéder à cette page, vous devez aller à l'URL suivante :

http://www.monsite.com/bonjour.php

Jusque-là, rien de bien nouveau. Ce que je vous propose d'apprendre à faire, c'est d'envoyer des informations à la page bonjour.php. Pour cela, on va ajouter à la fin de l'URL des informations, comme ceci :

http://www.monsite.com/bonjour.php?nom=Dupont&prenom=Jean

Ce que vous voyez après le point d'interrogation, ce sont des paramètres que l'on envoie à la page PHP. Celle-ci peut récupérer ces informations dans des variables. Voici comment on peut découper cette URL :

Structure URL


Le point d'interrogation sépare le nom de la page PHP des paramètres. Ensuite, les paramètres s'enchaînent selon la forme nom=valeur et sont séparés entre eux par le symbole &.

On peut écrire autant de paramètres que l'on veut ?


En théorie oui. Il suffit de les séparer par des & comme je l'ai fait. On peut donc voir une URL de la forme :

page.php?param1=valeur1&param2=valeur2&param3=valeur3&param4=valeur4 [...]

La seule limite est la longueur de l'URL. En général il n'est pas conseillé de dépasser les 256 caractères, mais parfois les navigateurs arrivent à gérer des URL plus longues. Quoiqu'il en soit vous l'aurez compris, on ne peut pas mettre un roman dans l'URL non plus. ;)

Créer un lien avec des paramètres



Maintenant que nous savons cela, nous pouvons créer des liens en HTML d'une page vers une autre qui transmettent des paramètres.

Imaginons que vous ayez 2 fichiers sur votre site :

  • index.php (l'accueil)
  • bonjour.php


Nous voulons faire un lien de index.php qui amène vers bonjour.php et qui lui transmet des informations dans l'URL.

Lien entre index.php et bonjour.php


Pour cela, ouvrez index.php (puisque c'est lui qui contiendra le lien) et insérez-y par exemple le code suivant :

Code : PHP
1
<a href="bonjour.php?nom=Dupont&amp;prenom=Jean">Dis-moi bonjour !</a>


Comme vous le voyez, le & dans le code a été remplacé par &amp; dans le lien. Ca n'a rien à voir avec le PHP, simplement en HTML on demande à ce que les & soient écrits &amp; dans le code source. Si vous ne le faites pas, le code ne passera pas la validation W3C.


Ce lien appelle la page bonjour.php et lui envoie 2 paramètres :

  • nom : Dupont
  • prenom : Jean


Vous avez sûrement deviné ce qu'on essaie de faire ici. On appelle une page bonjour.php qui va dire "Bonjour" à la personne dont le nom et le prénom ont été envoyés en paramètres.

Comment faire dans la page bonjour.php pour récupérer ces informations ? C'est ce que nous allons voir maintenant. :)

Récupérer les paramètres en PHP

Nous savons maintenant comment former des liens pour envoyer des paramètres vers une autre page. Nous avons pour cela ajouté des paramètres à la fin de l'URL.

Intéressons-nous maintenant à la page qui réceptionne les paramètres. Dans notre exemple, il s'agit de la page bonjour.php. Cette page va automatiquement créer un array au nom un peu spécial : $_GET. Il s'agit d'un array associatif (vous vous souvenez, nous avons étudié cela il y a peu !) dont les clés correspondent aux noms des paramètres envoyés en URL.

Reprenons notre exemple pour mieux voir comment cela fonctionne. Nous avons fait un lien vers : bonjour.php?nom=Dupont&prenom=Jean, cela signifie que nous aurons accès aux variables suivantes :

NomValeur
$_GET['nom'] Dupont
$_GET['prenom'] Jean


On peut donc récupérer ces informations, les traiter, les afficher, bref faire ce qu'on veut avec. Essayons pour commencer de les afficher, tout simplement.

Créez un nouveau fichier PHP que vous appellerez bonjour.php et placez-y le code suivant :

Code : PHP
1
<p>Bonjour <?php echo $_GET['prenom']; ?> !</p>


Bien sûr, pour une vraie page web il faudrait écrire toutes les informations d'en-tête nécessaires en HTML : le doctype, la balise <head>, etc. Ici, je ne mets pas tout ce code pour faire simple. La page ne sera pas très belle (ni valide W3C d'ailleurs) mais ce n'est pas notre problème ici. Nous faisons juste des tests.


Ici, nous affichons le prénom qui a été passé dans l'URL. Bien entendu, nous avons aussi accès au nom. Nous pouvons afficher le nom et le prénom sans problème :

Code : PHP
1
<p>Bonjour <?php echo $_GET['prenom'] . ' ' . $_GET['nom']; ?> !</p>


Comme vous le voyez j'en ai profité pour faire une petite concaténation comme nous avons appris à le faire. Ce code que vous voyez là n'est pas bien complexe : nous affichons le contenu de 2 cases de l'array $_GET. C'est vraiment très simple et il n'y a rien de nouveau. Tout ce qu'il fallait savoir, c'est qu'on peut retrouver les paramètres envoyés dans l'URL grâce à un array nommé $_GET.

Si vous voulez tester le résultat, je vous propose d'essayer en ligne ce que ça donne directement sur le Site du Zéro. Ce lien ouvre la page index.php :



Vous devriez faire le test aussi chez vous pour vous assurer que vous comprenez bien le fonctionnement ! Si besoin est, vous pouvez télécharger mes fichiers index.php et bonjour.php d'exemple.



Ne faites jamais confiance aux données reçues !

Il est impossible de terminer ce chapitre sans que je vous mette en garde contre les dangers qui guettent l'apprenti webmaster que vous êtes. Nous allons en effet découvrir qu'il ne faut JAMAIS faire confiance aux variables qui transitent de page en page, comme $_GET que nous étudions ici.

Le but de cette section est, je l'avoue, de vous faire peur. Car trop peu de développeurs PHP ont conscience des dangers et des failles de sécurité qu'ils peuvent rencontrer, ce qui risque pourtant de mettre en péril leur site web ! Oui je suis alarmiste, oui je veux que vous ayez (un peu) peur ! Mais rassurez-vous : je vais vous expliquer tout ce qu'il faut savoir pour que ça se passe bien et que vous ne risquiez rien. ;)

Ce qui compte, c'est que vous ayez conscience très tôt, dès maintenant, des problèmes que vous pourrez rencontrer lorsque vous recevrez des paramètres de l'utilisateur.

Tous les visiteurs peuvent trafiquer les URL



Si vous faites les tests des codes précédents chez vous, vous devriez tomber sur une URL de la forme :

http://localhost/tests/bonjour.php?nom=Dupont&prenom=Jean

On vous dit bien "Bonjour Jean Dupont !". Mais si vous êtes un peu bricoleur, vous pouvez vous amuser à changer les paramètres directement dans la barre d'adresse.

On peut facilement modifier les paramètres dans le navigateur


Essayez par exemple de modifier l'adresse pour :

http://localhost/tests/bonjour.php?nom=Dupont&prenom=Marc

Comme vous le voyez, ça marche ! N'importe qui peut facilement modifier les URL et y mettre ce qu'il veut : il suffit simplement de changer l'URL dans la barre d'adresse de votre navigateur.

Et alors, quel est le problème ? C'est pas plus mal non, si le visiteur veut adapter l'URL pour qu'on lui dise bonjour avec son vrai nom et son vrai prénom ? :euh:


Peut-être, mais cela montre une chose : on ne peut pas avoir confiance dans les données qu'on reçoit. N'importe quel visiteur peut les changer. Dans la page index.php j'ai fait un lien qui dit bonjour à Jean Dupont, mais la page bonjour.php ne va pas forcément afficher "Bonjour Jean Dupont !" puisque n'importe quel visiteur peut s'amuser à modifier l'URL.

Je vous propose de faire des modifications encore plus vicieuses et de voir ce qu'on peut faire pour éviter les problèmes qui en découlent.

Tester la présence d'un paramètre



Allons plus loin. Qu'est-ce qui empêche le visiteur de supprimer tous les paramètres de l'URL ? Par exemple, il peut très bien tenter d'accéder à :

http://localhost/tests/bonjour.php

Que va afficher la page bonjour.php ? Faites le test ! Elle va afficher quelque chose comme :

Code : Console
Bonjour 
Notice: Undefined index: prenom in C:\wamp\www\tests\bonjour.php on line 9

Notice: Undefined index: nom in C:\wamp\www\tests\bonjour.php on line 9
!


Que s'est-il passé ? On a essayé d'afficher la valeur de $_GET['prenom'] et de $_GET['nom']... Mais comme on vient de les supprimer de l'URL, ces variables n'ont pas été créées et donc elles n'existent pas ! PHP nous avertit qu'on essaie d'utiliser des éléments du tableau qui n'existent pas, d'où les "Undefined index".

Pour résoudre ce problème, on peut faire appel à une fonction un peu spéciale : isset(). Cette fonction teste si une variable existe. Nous allons nous en servir pour afficher un message spécifique si le nom ou le prénom sont absents.

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php
if (isset($_GET['prenom']) AND isset($_GET['nom'])) // On a le nom et le prénom
{
	echo 'Bonjour ' . $_GET['prenom'] . ' ' . $_GET['nom'] . ' !';
}
else // Il manque des paramètres, on avertit le visiteur
{
	echo 'Il faut renseigner un nom et un prénom !';
}
?>


Que fait ce code ? Il teste si les variables $_GET['prenom'] et $_GET['nom'] existent. Si elles existent, on dit bonjour au visiteur. S'il nous manque une des variables (ou les deux) on affiche un message d'erreur : "Il faut renseigner un nom et un prénom !".

Essayez maintenant d'accéder à la page bonjour.php sans les paramètres, vous allez voir qu'on gère bien le cas où le visiteur aurait retiré les paramètres de l'URL. :)

Est-ce que c'est vraiment la peine de gérer ce cas ? C'est vrai quoi, moi je ne m'amuse jamais à modifier mes URL et mes visiteurs non plus je pense !


Oui, oui, trois fois oui : il faut que vous pensiez à gérer le cas où des paramètres que vous attendiez viendraient à manquer.

Vous vous souvenez de ce que je vous ai dit ? Il ne faut jamais faire confiance à l'utilisateur. Tôt ou tard vous tomberez sur un utilisateur malintentionné qui essaiera de trafiquer l'URL pour mettre n'importe quoi dans les paramètres. Il faut que votre site soit prêt à gérer le cas.

Dans notre exemple, si on ne gérait pas le cas ça ne faisait rien de bien grave (ça affichait juste des messages d'erreur). Mais lorsque votre site web deviendra plus complexe, cela pourrait avoir de plus graves conséquences.

Un exemple ? Sur le Site du Zéro lui-même, nous avions une fois oublié de gérer le cas où un paramètre viendrait à manquer. Un utilisateur avait essayé de l'enlever "pour voir" et notre page PHP était faite de telle sorte que si le paramètre manquait, ça supprimait toutes les préférences de tous les membres inscrits du site !
Vous n'en êtes pas encore là, mais je tiens à vous sensibiliser aux problèmes potentiels que cela peut provoquer. Soyez donc vigilants dès maintenant et ne supposez jamais que vous allez recevoir tous les paramètres que vous attendiez.


Contrôler la valeur des paramètres



Allons plus loin dans notre tripatouillage vicieux de l'URL. On va modifier notre code source pour gérer un nouveau paramètre : le nombre de fois que le message doit être répété. Les paramètres vont donc être :

bonjour.php?nom=Dupont&prenom=Jean&repeter=8

Le paramètre repeter définit le nombre de fois qu'on dit bonjour sur la page. Sauriez-vous adapter notre code pour qu'il dise bonjour le nombre de fois indiqué ? Voici la solution que je vous propose :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
if (isset($_GET['prenom']) AND isset($_GET['nom']) AND isset($_GET['repeter']))
{
	for ($i = 0 ; $i < $_GET['repeter'] ; $i++)
	{
		echo 'Bonjour ' . $_GET['prenom'] . ' ' . $_GET['nom'] . ' !<br />';
	}
}
else
{
   echo 'Il faut renseigner un nom, un prénom et un nombre de répétitions !';
}
?>


On teste si le paramètre repeter existe lui aussi (avec isset($_GET['repeter'])). Si tous les paramètres sont bien là, on fait une boucle (j'ai choisi de faire un for, mais on aurait aussi pu faire un while). La boucle incrémente une petite variable $i pour répéter le message de bienvenue le nombre de fois indiqué.

Le résultat ? Si on va sur :

http://localhost/tests/bonjour.php?nom=Dupont&prenom=Jean&repeter=8

Alors le message de bienvenue s'affichera 8 fois :

Code : Console
Bonjour Jean Dupont !
Bonjour Jean Dupont !
Bonjour Jean Dupont !
Bonjour Jean Dupont !
Bonjour Jean Dupont !
Bonjour Jean Dupont !
Bonjour Jean Dupont !
Bonjour Jean Dupont !


Nous avons amélioré notre page pour qu'elle puisse dire bonjour plusieurs fois, et ce nombre de fois est personnalisable dans l'URL. Très bien.

Maintenant, mettez-vous dans la peau du méchant. Soyez méchant. Soyez vicieux. Qu'est-ce qu'on pourrait faire que nous n'avions pas prévu juste en modifiant l'URL ?

J'ai une idée ! On peut mettre un nombre de répétitions très grand, par exemple 1984986545665156. La page PHP va boucler un très grand nombre de fois et sûrement que votre PC ne pourra jamais supporter une telle charge de travail. :diable:

http://localhost/tests/bonjour.php?nom=Dupont&prenom=Jean&repeter=1984986545665156

Si vous avez peur d'essayer, je vous rassure : votre PC ne va pas prendre feu en faisant ça. Par contre, il va se mettre à consommer énormément de mémoire pour stocker tous les messages bonjour et n'arrivera sûrement pas jusqu'au bout (PHP s'arrête au bout d'un certain temps d'exécution). Ou alors s'il y arrive, votre page va être extrêmement surchargée de messages bonjour.

Mon dieu c'est horrible ! Comment peut-on empêcher ça ?


En étant plus malin et surtout plus prévoyant. Voici ce qu'il faut anticiper :

  • Le cas où le nombre qu'on vous envoie n'est pas une valeur raisonnable.
    • Par exemple on peut dire que si on dépasse 100 fois, c'est trop, et il faut refuser d'exécuter la page.
    • De même, que se passe-t-il si je demande de répéter "-4 fois" ? Ca ne devrait pas être autorisé. Il faut que le nombre soit au moins égal à 1.
  • Le cas où la valeur n'est pas logique, où elle n'est pas du tout ce qu'on attendait. Rien n'empêche le visiteur de remplacer la valeur du paramètre repeter par du texte !
    • Que se passe-t-il si on essaie d'accéder à bonjour.php?nom=Dupont&prenom=Jean&repeter=grenouille ? Cela ne devrait pas être autorisé. Le mot "grenouille" n'a pas de sens, on veut un nombre entier positif.
    • Que se passe-t-il si on essaie d'accéder à bonjour.php?nom=Dupont&prenom=Jean&repeter=true ? Cela ne devrait pas être autorisé non plus, on attendait un nombre entier positif, pas un booléen.


Pour résoudre ces problèmes, on doit :

  1. Vérifier que repeter contient bien un nombre.
  2. Vérifier ensuite que ce nombre est compris dans un intervalle raisonnable (entre 1 et 100 par exemple).


Pour vérifier que repeter contient bien un nombre, une bonne solution pourrait être de forcer la conversion de la variable en type entier (int). On peut utiliser pour cela ce qu'on appelle le transtypage, une notion qu'on n'a pas vue jusqu'ici mais qui est très simple à comprendre. Regardez ce code :

Code : PHP
1
2
3
<?php
$_GET['repeter'] = (int) $_GET['repeter'];
?>


Il faut lire cette instruction de droite à gauche. Le (int) entre parenthèses est comme un tuyau de conversion. Tout ce qui transite à travers ressort forcément en une valeur de type int (entier).

Transtypage


Si la valeur est bien un entier (par exemple 14) alors elle n'est pas modifiée. En revanche, si la valeur contient autre chose qu'un entier (par exemple "grenouille") elle est transformée en entier. Ici, comme PHP ne peut pas associer de valeur à grenouille, il lui donne 0.

Après avoir exécuté cette instruction, la variable $_GET['repeter'] contient maintenant forcément un nombre entier. Il ne reste plus qu'à vérifier que ce nombre est bien compris entre 1 et 100 à l'aide d'une condition, ce que vous savez faire normalement. ;)

Voici donc le code final sécurisé qui prévoit tous les cas pour éviter d'être pris au dépourvu par un utilisateur malintentionné :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<?php
if (isset($_GET['prenom']) AND isset($_GET['nom']) AND isset($_GET['repeter']))
{
	// 1 : On force la conversion en nombre entier
	$_GET['repeter'] = (int) $_GET['repeter'];

	// 2 : Le nombre doit être compris entre 1 et 100
	if ($_GET['repeter'] >= 1 AND $_GET['repeter'] <= 100) 
	{	
		for ($i = 0 ; $i < $_GET['repeter'] ; $i++)
		{
			echo 'Bonjour ' . $_GET['prenom'] . ' ' . $_GET['nom'] . ' !<br />';
		}
	}
}
else
{
   echo 'Il faut renseigner un nom, un prénom et un nombre de répétitions !';
}
?>


Cela fait beaucoup de conditions pour quelque chose qui était à la base assez simple. Mais c'était nécessaire. Vous devrez toujours faire très attention comme on l'a fait à prévoir tous les cas les plus tordus :

  • Vérifier que tous les paramètres que vous attendiez sont bien là.
  • Vérifier qu'ils contiennent bien des valeurs correctes comprises dans des intervalles raisonnables.


Si vous gardez cela en tête, vous n'aurez pas de problèmes. :)

Nous n'avons pas encore vu tous les risques liés aux données envoyées par l'utilisateur. Cette première approche devrait déjà vous avoir sensibilisé au problème, mais nous irons plus loin dans le chapitre suivant pour finir de couvrir ce sujet. Tout ceci est un peu complexe je suis d'accord, mais c'est réellement important !

Q.C.M.

Combien de paramètres est-ce qu'on envoie à cette page ?

page.php?code=1251&ville=boston
Que contient l'array $_GET ?
$_GET est un array de type...
Pourquoi faut-il vérifier systématiquement si les valeurs que l'on reçoit via $_GET correspondent bien à ce qu'on attendait ?

Statistiques de réponses au QCM

L'utilisation des paramètres envoyés dans l'URL est simple : il suffit de récupérer ces valeurs dans l'array $_GET. Vous ne devriez pas avoir eu de mal à comprendre cela dans la première moitié de ce chapitre.

En revanche, j'ai particulièrement insisté dans ce chapitre sur le fait qu'il faut être très vigilant quand on récupère des données qui sont modifiables par l'utilisateur. N'ayez jamais confiance. Les programmeurs disent "Never trust user input" (ne faites jamais confiance en ce que l'utilisateur a saisi). Cette phrase devrait dès aujourd'hui être affichée sur un mur de votre chambre.
Trop de programmeurs débutants ont fait confiance à ce que l'utilisateur allait saisir ("allez quoi, il ne va jamais rentrer grenouille à la place d'un nombre !") et je peux vous dire qu'ils s'en mordent aujourd'hui les doigts.

Heureusement ça ne sera pas votre cas ! J'ai été alarmiste, voire même un peu lourd dans ce chapitre, mais c'est pour votre bien. Vous allez voir, vous allez très vite avoir le réflexe de tester les données que votre page PHP reçoit !

Never trust user input.
Never trust user input.
Never trust user input.
Never trust user input.
Chapitre précédent Sommaire Chapitre suivant

Partager

43 commentaires pour "Transmettre des données avec l'URL"
Note moyenne : 3.61 / 4 (2518 votes)
Pseudo Commentaire
Hors ligne Rafikiki # Posté le 07/05/2012 à 22:33:32
Avatar

Mmmmmhhhh, c'est donc un des moyens qu'on les anonymous de trafiquer les données :D , restons vigilant!!! :o
Sinon comme d'hab rien à dire tuto impeccable :) , merci maître Mateo! :lol:
Hors ligne homer.43.simspon # Posté le 08/05/2012 à 10:53:58

bonjour je voudrai definir l'inclusion d'une page avec la fonction include et données le nom de la page dans l'url mais je n'y arrive pas merci de votre aide
Hors ligne fredmart # Posté le 16/05/2012 à 08:10:27

bonjour a tous!!

voila je m'essaye a la construction d'un site et l'a j'ai intégré dans ma page d'accueil une liste déroulante de choix, mais j'aimerai que lorsqu'un choix a l'aide du bouton "envoyer"
<input type="submit" value="Envoyer" />
est sélectionné, alors en validant, ça me renvoi sur la page demander (index.php), mais l'as dans ma barre il est noté "traitement.php"

si quelqu'un connait la réponse...?!
Hors ligne fredmart # Posté le 16/05/2012 à 09:25:26

bon j'ai trouver un bon debut de mon probleme, "traitement.php" est une page fictive utilisé pour le cours, mais dans ce cas quel est la méthode que je doit utiliser pour que si je selection un choix sa m'envoi a sa page et si c'est un choix différent sa m'envoi a la page sélection aussi
Hors ligne ludo0162 # Posté le 17/05/2012 à 15:51:16

Salut a tous
Super site . Merci
Comme certain de mes camarades ,j'ai du mal a comprendre la dernière partie de: Ne faites jamais confiance aux données reçues ! )
J'ai beau faire les modifications dans l'URL , je ne vois pas les effets que tu décris
Donc je ne vois pas non plus l'effet positif des correctif

Sinon super job
encore merci

Voir tous les commentaires