I. Format d'une URL

Les URLUniform Resource Locator sont les chemins des ressources sur internet. Ils sont uniques et permettent d'accéder à n'importe quel document.

I-A. Syntaxe générale

<schéma>://<utilisateur>:<mot de passe>@<machine>:<port>/<chemin>?<paramètres>#<fragment>

Champ Description
schéma protocole utilisé (http, ftp, .)
machine nom de domaine ou adresse IP du serveur
utilisateur nom d'utilisateur pour certains protocoles nécessitant une identification (ftp, telnet, .)
mot de passe mot de passe pour l'authentification
port n° de port sur lequel se connecter, les protocoles ont un port par défaut (80 pour http)
chemin chemin complet de la ressource : succession des répertoires à parcourir pour l'atteindre plus son nom complet
paramètres liste des noms de paramètres et de leurs valeurs
fragment identifiant d'un lien interne à une page HTML (créé par <a name="">)

I-B. Syntaxe de la liste des paramètres

Le champ <paramètres> ci-dessus peut être décomposé plus finement :

<couple (nom,valeur)>&<couple (nom,valeur)>&.

I-C. Syntaxe du couple (nom, valeur)

Le champ <couple (nom,valeur)> peut être décomposé encore plus finement :

nom=valeur

I-D. Résumé

Le caractère ? indique que la suite de l'URL correspond à des paramètres et ne fait pas partie du nom de fichier. Le caractère = sépare un nom de paramètre et sa valeur transmise. Le caractère & sépare deux couples (nom, valeur).

Pour faire face au cas général d'un paramètre dont la valeur contient des caractères interdits, on utilisera les fonctions de codage.

I-E. Exemple concrêt

 
Sélectionnez
<a href="index.php?imprim=yes&user_id=75">Version imprimable</a> 

Dans cet exemple on transmet deux variables au script index.php : $imprim de valeur "yes" et $user_id de valeur "75".

II. Passage de paramètres

II-A. Passage d'une chaîne de caractères

Une URL étant d'abord une chaîne de caractère, la valeur reçue par le script sera de type chaîne de caractères.

Script de départ
 
Sélectionnez
<a href="page.php?str=bonjour">
Script d'arrivée
 
Sélectionnez
echo $str;
Affiche : bonjour

II-B. Passage d'un entier

Le cast implicite et le faible typage des variables en PHP, provoque une conversion directe de la chaîne "20" en l'entier 20 lors de son utilisation dans un calcul ou un test.

Script de départ
 
Sélectionnez
<a href="page.php?i=20">
Script d'arrivée
 
Sélectionnez
echo $i*5;
Affiche : 100

II-C. Passage d'un flottant

De la même manière que pour un entier, un flottant sera automatiquement traduit en flottant lors de son utilisation.

Script de départ
 
Sélectionnez
<a href="page.php?x=5.23">
Script d'arrivée
 
Sélectionnez
echo f($x);
Affiche : 89.24

II-D. Passage d'un tableau

Pour passer un tableau à un script, il faut passer chaque élément du tableau séparément. Le nom du paramètre sera le nom du tableau, suivi de crochets [].

Script de départ
 
Sélectionnez
$tab = array{ "Hugo", "ETIEVANT", 1980 };
 
Sélectionnez
<a href="page.php?tab[]=Hugo&tab[]=ETIEVANT&tab[]=1980">
Script d'arrivée
 
Sélectionnez
echo $tab[0], " ", $tab[1], " ", $tab[2];
Affiche : Hugo ETIEVANT 1980
Script de départ
 
Sélectionnez
$tab = array{ "Hugo", "ETIEVANT", 1980 };
 
Sélectionnez
<a href="page.php?tab=Hugo&tab=ETIEVANT&tab=1980">
Script d'arrivée
 
Sélectionnez
echo $tab;
Affiche : 1980

II-E. Passage d'un tableau associatif

Un tableau associatif associe un élément à une clé. Pour le passer en paramètre, il faut ajouter entre les crochets le nom de la clé.

Script de départ
 
Sélectionnez
$tab = array{ "prenom" => "Hugo", "nom" => "ETIEVANT", "age" => 1980 };
 
Sélectionnez
<a href="page.php?tab[prenom]=Hugo&tab[nom]=ETIEVANT&tab[age]=1980">
Script d'arrivée
 
Sélectionnez
echo $tab["prenom"], " ", $tab["nom"], " ", $tab["age"];
Affiche : Hugo ETIEVANT 1980

II-F. Linéariser une variable

Il n'est pas du tout pratique de passer en paramètre un tableau avec 150 champs comme dans l'exemple précédent.

Heureusement, il existe un couple de fonctions serialise() et unserialise() qui permet traduire une variable en une chaîne de caractères que l'on peut passer facilement en paramètre sans perdre ni leur structure ni leur type.

Pour récupérer une variable linéarisée, et retrouver la valeur de la variable, on utilise unserialize().

Types linéarisables
entier
flottant
chaîne de caractères
tableau
tableau multidimensionel
tableau associatif
objet

Après avoir linéarisé notre variable, on doit coder cette chaîne avant de la passer en param et en protéger les slashs éventuels.

Script de départ
 
Sélectionnez
$tab = array{ "prenom" => "Hugo", "nom" => "ETIEVANT", "age" => 1980 };
		 <a href="test.php3?str=".addslashes(urlencode(serialize($tab)))."">
Script d'arrivée
 
Sélectionnez
$tab = unserialize(urldecode(stripslashes($str)));
		 echo $tab["prenom"], " ", $tab["nom"], " ", $tab["age"];
Affiche : Hugo ETIEVANT 1980

Attention à une erreur commune : bien respecter l'ordre des fonctions composées ! Dans le script de départ : linéariser, coder et protéger les slashs. Dans le script d'arrivée, l'opération inverse : déprotéger les slashs, décoder, délinéariser.

II-G. Passage d'un objet

Tout comme pour le tableau, un objet n'étant pas un type de base (nombre, chaîne, booléen), il ne peut être passé directement en paramètre.

Travaillons sur l'objet moi instance de la classe Personne :

 
CacherSélectionnez

On pourrait en passer chacun des attributs en paramètre séparement dans l'URL comme le montre l'exemple suivant :

Script de départ
 
Sélectionnez
<a href="page.php?n=".$moi->nom."&p=".$moi->prenom."&a=".$moi->age.">
Script d'arrivée
 
Sélectionnez
$moi = new Personne($n, $p, $a);
		 $moi->afficher();
Affiche : Hugo ETIEVANT 1980

Mais cette méthode est laborieuse, il est plus simple de ne passer qu'une seule valeur en paramètre. Or on sait que la linéarisation permet de "compresser" une variable - même complexe - dans une seule valeur de type chaîne de caractères. On va donc linéariser notre objet.

De plus, la linéarisation permet de conserver les connexions ouvertes vers les bases de données ! Par contre les méthodes ne sont pas conservées.

Script de départ
 
Sélectionnez
<a href="page.php?moi=".addslashes(urlencode(serialize($moi)))."">
Script d'arrivée
 
Sélectionnez
$moi = unserialize(urldecode(stripslashes($moi)));

III. Codage

Une URL ne peut pas comporter n'importe quel caractère et certains d'entre eux ont une fonction bien précise. Il est alors important que la valeur d'un paramètre ne contienne pas de caractère qui puisse être mal interprété. On a donc besoin de coder les valeurs des paramètres pour s'assurer qu'ils vont bien arriver à destination tels que la source les a envoyé.

Ce codage peut être plus ou moins compliquer. Cela va du simple remplacement de quelques caractères spéciaux jusqu'au changement de base du codage des caractères (passage de 8 bits à 7 bits) afin de transformer des caractères binaires en simples lettres.

III-A. Codage de base

urlencode : encode une chaîne en URL.
urldecode : décode une chaîne encodée URL.

urlencode($str) : code la chaîne $str. Les espaces sont remplacés par des signes plus (+). Ce codage est celui qui est utilisé pour poster des informations dans les formulaires HTML. Le type MIME utilisé est application/x-www-form-urlencoded.

Exemple : echo <a href=\"$PHP_SELF?foo=".urlencode($foo)."\">Foo</a>";

NB : Pour être accessible, la valeur du paramètre devra par la suite être décodée dans le script d'arrivé par la fonction réciproque adéquate.

III-B. Codage complet

rawurlencode : encode une chaîne en URL, selon la RFC1738.
rawurldecode : décode une chaîne URL, selon la RFC1738.

rawurlencode($str) : code la chaîne $str. Remplace tous les caractères interdits par leur codage équivalent hexadécimal.

Exemple : echo <a href=\"$PHP_SELF?foo=".rawurlencode($foo)."\">Foo</a>";

III-C. Codage plus évolué

base64_encode : encode une chaîne en MIME base64.
base64_decode : décode une chaîne en MIME base64

base64_encode($str) : code la chaîne $str en base64. Cet encodage permet à des informations binaires d'être manipulées par les systèmes qui ne gèrent pas correctement les codes 8 bits (code ASCII 7 bit étendu aux accents européens), comme par exemple, les corps de mail qui en général sont américains et ne gèrent que les 7 bits. Une chaîne encodée en base64 a une taille d'environ 33 % supérieure à celle des données initiales.

Exemple : echo <a href=\"$PHP_SELF?foo=".base64_encode($foo)."\">Foo</a>";

Comparatif des trois codages  
Sans codage René & Cie : 30%-5*20
urlencode Ren%E9+%26+Cie+%3A+30%25-5%2A20
rawurlencode Ren%E9%20%26%20Cie%20%3A%2030%25-5%2A20
base64_encode UmVu6SAmIENpZSA6IDMwJS01KjIw

IV. Parser une URL

Il peut être intéressant d'extraire d'une URL (ce peut être $PHP_SELF ou $HTTP_REFERER) certains éléments comme le protocole, le chemin, .

parse_url($str) : retourne un tableau associatif contenant les différents éléments de l'URL passée en paramètre. Les champs sont les suivants : scheme (protocole), host (domaine), port (n° de port), user (nom d'utilisateur), pass (mot de passe), path (chemin de la ressource), query (paramètres et valeurs), et fragment.

Exemple : $tab = parse_url("http://www.cia.gov:8080/search/form.php?var=val#toc3");
Cet exemple retourne le tableau suivant :

Champs Valeur Description
scheme http protocole utilisé
query var=val question posée, c'est-à-dire la liste des paramètres et de leurs valeurs respectives
path search/form.php chemin et nom complet de la ressource demandée
port 8080 port utilisé sur le serveur
host www.cia.gov nom de domaine du serveur
fragment toc3 nom de fragment (lien interne à la page HTML)

V. Interpréter les variables d'une URL

parse_str($str) : analyse la chaîne $str comme si c'était une URL et en extrait les variables et valeurs respectives qui seront alors connues dans la suite du script. Cette fonction évite d'avoir à créer ses propres fonctions d'analyse de champs de base de données où l'on aurait sauvegardé une URL.

Exemple :
$str = "nom=jean+pierre&email[]=moi@ici.fr&email[]=moi@labas.com";
parse_str($str);
echo $nom, $email[0], $email[1];

VI. Portée des variables

Jusqu'à la version PHP 4.2.0, les paramètres passés dans l'URL étaient automatiquement connus sous forme de variables globales du script destinataire. Mais depuis la version 4.2.0, ce n'est plus le cas à cause du changement de la valeur par défaut du paramètre register_global du fichier de configuration php.ini du serveur. Ce paramètre était auparavent à On, il est désormais à Off. Ce changement impose de recourir désormais aux tableaux dit super globaux de PHP.

Exemple : http://www.monsite.com/home.php?id=40&action=buy
Avant PHP 4.2.0, le script d'arrivée disposait automatiquement des variables globales $id et $action de valeurs respectives 40 et "buy" car le serveur était configuré à register_global=On.
À cette époque, on pouvait aussi procéder autrement à l'aide d'une méthode indirecte qui consistait à l'utilisation du tableau $HTTP_GET_VARS qui est un tableau associatif dont les clés sont les paramètres passés dans l'URL.

Script de départ
 
Sélectionnez
<a href="http://www.monsite.com/home.php?id=40&action=buy">
Script d'arrivée
 
Sélectionnez
echo $id, " ", $action;
Affiche : 40 buy
 
Sélectionnez
echo $HTTP_GET_VARS["id"], " ", $HTTP_GET_VARS["action"];
Affiche aussi : 40 buy

Maintenant, depuis PHP 4.2.0, le script ne connait plus de variables globales appelées $id et $action !
Pour récupérer ces paramètres, on va faire appel au tableau super global $_GET qui contient les mêmes informations que $HTTP_GET_VARS. La seule différence entre ces deux tableaux, c'est que $HTTP_GET_VARS est une variable globale alors que $_GET est une variable super globale. Cette différence réside dans la portée de ces variables. Une variable globale est connue dans le corps du script mais pas dans ses fonctions (sauf à les déclarer avec le mot clé global). Une variable super globale est automatiquement connue partout sans besoin de les déclarer dans les fonctions.

La nouvelle méthode de manipulation des paramètres passés en URL est la suivante :

Script de départ
 
Sélectionnez
<a href="http://www.monsite.com/home.php?id=40&action=buy">
Script d'arrivée
 
Sélectionnez
echo $_GET["id"], " ", $_GET["action"];
Affiche : 40 buy

Mais afin d'éviter de chambouler l'écriture de vos scripts, vous pouvez vous contenter de rajouter la déclararation suivante en début de script : $id = $_GET["id"] et $action = $_GET["action"].

Script de départ
 
Sélectionnez
<a href="http://www.monsite.com/home.php?id=40&action=buy">
Script d'arrivée
 
Sélectionnez
$id = $_GET["id"];
		 $action = $_GET["action"];
		 echo $id, " ", $action;
Affiche : 40 buy

VII. Codage hexadécimal des caractères spéciaux

On a vu dans Codage, que certains caractères avaient des propriétés spéciales qui en faisait de mauvais candidats pour un passage directe dans l'URL dans codage préalable.

Le tableau suivant montre la liste des caractères spéciaux avec leur code hexadécimal.

Caractère Code hexadécimal
tabulation %09
espace %20
" %22
' %60
# %23
% %25
& %26
? %3F
@ %40
( %28
) %29
[ %5B
] %5D
{ %7B
} %7D
/ %2F
\ %5C
| %7C
< %3C
> %3E
= %3D
^ %5E
~ %7E
: %3A
; %3B
, %2C
. %2E

Exemple d'un fichier dont le nom sous Windows est Planning de suivi (2003).xls devient après codage des caractères spéciaux : Planning%20de%20suivi%20%282003%28.xls.

Voici le tableau de correspondance du début de la table MIME de la police de cette page :

  %1E      %1F      %20    ! %21    " %22    # %23    $ %24    % %25    & %26    ' %27   
( %28    ) %29    * %2A    + %2B    , %2C    - %2D    . %2E    / %2F    0 %30    1 %31   
2 %32    3 %33    4 %34    5 %35    6 %36    7 %37    8 %38    9 %39    : %3A    ; %3B   
< %3C    = %3D    > %3E    ? %3F    @ %40    A %41    B %42    C %43    D %44    E %45   
F %46    G %47    H %48    I %49    J %4A    K %4B    L %4C    M %4D    N %4E    O %4F   
P %50    Q %51    R %52    S %53    T %54    U %55    V %56    W %57    X %58    Y %59   
Z %5A    [ %5B    \ %5C    ] %5D    ^ %5E    _ %5F    ` %60    a %61    b %62    c %63   
d %64    e %65    f %66    g %67    h %68    i %69    j %6A    k %6B    l %6C    m %6D   
n %6E    o %6F    p %70    q %71    r %72    s %73    t %74    u %75    v %76    w %77   
x %78    y %79    z %7A    { %7B    | %7C    } %7D    ~ %7E     %7F    ? %80    \x81 %81   
%82    ƒ %83    %84    %85    %86    %87    ˆ %88    %89    Š %8A    %8B   
O %8C    \x8D %8D    Ž %8E    \x8F %8F    \x90 %90    %91    ' %92    %93    %94    %95   
- %96    - %97    ˜ %98    %99    š %9A    %9B    o %9C    \x9D %9D    ž %9E    Ÿ %9F   
  %A0    ¡ %A1    ¢ %A2    £ %A3    ¤ %A4    ¥ %A5    ¦ %A6    § %A7    ¨ %A8    © %A9   
ª %AA    « %AB    ¬ %AC    ­ %AD    ® %AE    ¯ %AF    ° %B0    ± %B1    ² %B2    ³ %B3   
´ %B4    µ %B5    %B6    · %B7    ¸ %B8    ¹ %B9    º %BA    » %BB    ¼ %BC    ½ %BD   
¾ %BE    ¿ %BF    À %C0    Á %C1    Â %C2    Ã %C3    Ä %C4    Å %C5    Æ %C6    Ç %C7   
È %C8    É %C9    Ê %CA    Ë %CB    Ì %CC    Í %CD    Î %CE    Ï %CF    Ð %D0    Ñ %D1   
Ò %D2    Ó %D3    Ô %D4    Õ %D5    Ö %D6    × %D7    Ø %D8    Ù %D9    Ú %DA    Û %DB   
Ü %DC    Ý %DD    Þ %DE    ß %DF    à %E0    á %E1    â %E2    ã %E3    ä %E4    å %E5   
æ %E6    ç %E7    è %E8    é %E9    ê %EA    ë %EB    ì %EC    í %ED    î %EE    ï %EF   
ð %F0    ñ %F1    ò %F2    ó %F3    ô %F4    õ %F5    ö %F6    ÷ %F7    ø %F8    ù %F9   
ú %FA    û %FB    ü %FC    ý %FD    þ %FE    ÿ %FF      %100      %101      %102      %103   

En voici le code source PHP :

 
CacherSélectionnez