Zebra3 a écrit a écrit :
euh... en fait non ... c pas ça !!
$PHP_SELF renvoie simplement le chemin et le nom du fichier ! pas la requête ! pour ça il existe (au moins en php4) une variable spéciale : $QUERY_STRING ! il suffisait d'y penser !
|
En fait le QUERY_STRING est la fin de la requête uniquement, c'est à dire ce qui est derrière le "?". avec PHP_SELF qui indique le chemin local et le nom du fichier cela n'en fait pas pour autant une URL valide dans certains cas (cas des serveurs virtuels) car le nom de domaine utilisé par le client pour atteindre le serveur n'est pas forcément celui utilisé par le serveur.
En fait il faut regarder le contenu de la requête HTTP de la forme:
<GET-ou-POST> [/<chemin>]/[<ressource>][?<chaine-requête>] HTTP/1.<x>
Host: <nom.de.domaine.vu.par.le.client>
<autres-entêtes-MiME: valeur...>
[Content-Type: <xxx>/<xxx>
Content-Length: <xxx>
<données POST>]
Cela correspond à l'URL réellement tapée par le client ou demandée par un proxy HTTP.
On retrouve toutes les variables dans PHP, mais le nom de domaine peut être différent de celui vu par le client. Hors pour renvoyer au client un REFRESH ou un redirecteur vers une autre ressource, il est nécessaire de lui indiquer le bon nom d'hôte (sauf si justement le redirecteur sert à justement indiquer un autre hôte que celui demandé par le client, sans changer le chemin ou le nom de la ressource, ni les données de la requête).
Et l'hôte saisi par le client est une donnée d'entête, et ne correspond pas forcément au nom de domaine utilisé en interne par le serveur (cas des serveurs virtuels, où pleins de domaines différents sont servis par une ou plusieurs machines serveurs, dont le ou les noms de domaine n'ont rien à voir).
D'ailleur même le chemin peut être différent en PHP de celui indiqué par le client (exemple: sur Free.fr, un script PHP à l'adresse 'http://nom-du-site.free.fr/script.php' s'exécute en PHP avec 'www.free.fr' comme nom de serveur local et '/nom-du-site/script.php' dans $PHP_SELF, car le serveur de Free est un serveur virtuel servant de nombreux domaines différents, et le chemin du fichier exécuté et indiqué dans PHP_SELF contient le nom du sous-domaine demandé par le client).
Sur Free.fr (ou tous les serveurs gratuits en général qui proposent des sites avaec un nom de sous-domaine) c'est même pire: la requête ci-dessus parvient en fait d'abord sur un serveur proxy HTTP référencé par le serveur DNS du domaine free.fr.
Supposons donc qu'un client visitant notre site tape l'URL "http://nom-du-site.free.fr/script.php" dans la barre d'adresse de son navigateur. Le navigateur interroge le serveur DNS de Free.fr gérant "le domaine nom-du-site.free.fr" et trouve l'adresse IP d'un des serveurs proxy de Free chargé de faire transiter les requêtes des sites d'abonnés. Le proxy de Free.fr reçoit d'Internet:
GET /script.php HTTP/1.<x>
Host: nom-du-site.free.fr
...
Le proxy HTTP détermine ensuite le serveur web qui va servir la requête pour le site nom-du-site.free.fr. Supposons qu'il détermine que c'est le serveur www3.free.fr qui va traiter la requête, il la lui traduit en HTTP/1.1 (même si le client utilisait HTTP/1.0: c'est le proxy qui se charge de traduire le protocole en fonction du client):
GET /nom-du-site/script.php HTTP/1.1
Host: www3.free.fr
...
Et là le nom du domaine demandé par le client a complètement disparu, et le chemin de la page a changé, quand le serveur web reçoit la requête et l'envoie au moteur PHP qui va interpréter le script demandé !
Cela va un peu plus loin: pour des raisons de sécurité entre les comptes, le serveur web ne transmet pas la requête directement au script PHP, mais change de compte utilisateur Unix pour utiliser le compte de l'utilisateur nom-du-site, puis effectue un chroot pour que la racine "/" contienne la racine effective du site. Mais la requête HTTP n'est pas modifée pour autant. Le moteur PHP exécute donc bien le script qu'il trouve dans "/script.php" et non dans "/nom-du-site/script.php" (de sorte que si le script a besoin d'accéder à des fichiers, il n'y aura pas d'erreur dans le chemin et le script n'accédera qu'aux fichiers du compte "nom-du-site".
Tout ce traitement est nécessaire à cause d'une limite du serveur Apache: s'il gère bien les nom de domaines virtuels, il lui est par contre impossible de changer sa configuration en ligne sans redémarrer. Et Free ne veut pas toucher aux fichiers de configuration d'Apache qui tourne sur ses serveurs comme www3.free.fr. Espérons qu'une nouvelle version d'Apache permettra à Free de reconfigurer dynamiquement ses serveurs web, de sorte que le serveur proxy deviendra du passé et sera inutile, supprimant ainsi l'effet de bord produit sur les requêtes HTTP vues des scripts PHP.
Quant au résultat du script, il est revoyé au serveur proxy, qui se charge de le remettre au client. Mais le navigateur du client n'y voit que du feu !
Aussi il faut être prudent, et utiliser les variables des entêtes HTTP pour former une chaine valide pour le client !
Quant à $HTTP_REFERER, s'il a une valeur, il indique la valeur de l'entête "Http-Referer: xxxx" indiqué par le client, et qui mentionne l'URL précédemment visitée par le client (généralement l'URL de la page où il a cliqué un lien menant à la ressource PHP ici demandée, ou bien l'URL de la page où figure une balise d'image <img> ou d'objet <object> ou <embed> dont l'URL est le script PHP demandé, ou bien l'URL de la page contenant un <script> dont la source se réfère au script PHP demandé):
Pour les scripts PHP qui génèrent des images (par exemple un compteur graphique) c'est très utile pour affecter savoir de quel compteur il s'agit, ou pour contrôler l'usage du script PHP par le seul site habilité à s'y référer.
La variable $HTTP_REFERER n'est pas renseignée quand le client tape directement une URL dans la barre d'adresse, car il n'y a pas de page référente (comment indiquer l'URL du navigateur?) et le navigateur ne la transmet en principe pas, quelle que soit la page précédemment affichée par ce navigateur (il peut très bien ne pas y en avoir). Elle est renseignée par contre en cas de redirection par un META REFRESH: le HTTP-REFERER contient l'URL de la page qui contenait ce META.
[edit]--Message édité par verdy_p--[/edit]