web-dev-qa-db-fra.com

PHP_SELF vs PATH_INFO vs SCRIPT_NAME vs REQUEST_URI

Je construis une application PHP dans CodeIgniter. CodeIgniter envoie toutes les demandes au contrôleur principal: index.php. Cependant, je n'aime pas voir index.php dans l'URI. Par exemple, http://www.example.com/faq/whatever acheminera vers http://www.example.com/index.php/faq/whatever. J'ai besoin d'un moyen fiable pour qu'un script connaisse son adresse, ainsi il saura quoi faire avec la navigation. J'ai utilisé mod_rewrite, conformément à la documentation de CodeIgniter.

La règle est la suivante:

RewriteEngine on
RewriteCond $1 !^(images|inc|favicon\.ico|index\.php|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L] 

Normalement, je vérifierais simplement php_self, mais dans ce cas c'est toujours index.php. Je peux l'obtenir à partir de REQUEST_URI, PATH_INFO, etc., mais j'essaie de décider lequel sera le plus fiable. Est-ce que quelqu'un sait (ou sait où trouver) la différence réelle entre PHP_SELF, PATH_INFO, SCRIPT_NAME et REQUEST_URI? Merci de votre aide!

Note : J'ai dû ajouter des espaces, car SO voit le trait de soulignement et le met en italique pour une raison quelconque. 

Mise à jour : Correction des espaces.

92
Eli

La documentation PHP peut vous dire la différence:

'PHP_SELF'

Le nom de fichier du script en cours d'exécution, par rapport à la racine du document. Par exemple, $ _SERVER ['PHP_SELF'] dans un script à l'adresse http://example.com/test.php/foo.bar serait /test.php/foo.bar. La constante _FILE_ contient le chemin d'accès complet et le nom du fichier actuel (inclus). Si PHP est exécuté en tant que processeur de ligne de commande, cette variable contient le nom du script depuis PHP 4.3.0. Auparavant, ce n'était pas disponible. 

'SCRIPT_NAME'

Contient le chemin du script actuel. Ceci est utile pour les pages qui doivent se désigner elles-mêmes. La constante _FILE_ contient le chemin d'accès complet et le nom du fichier actuel (inclus).

'REQUEST_URI'

L'URI qui a été donné pour accéder à cette page; par exemple, '/index.html'.

PATH_INFO ne semble pas être documenté ...

46
Jeremy Ruten

Quelques exemples pratiques des différences entre ces variables:
Exemple 1 . PHP_SELF est différent de SCRIPT_NAME only lorsque l'URL demandée est sous la forme:
http://example.com/test.php/foo/bar

[PHP_SELF] => /test.php/foo/bar
[SCRIPT_NAME] => /test.php

(Cela semble être le seul cas où PATH_INFO contient des informations sensibles [PATH_INFO] => /foo/bar) Remarque: cette fonctionnalité était différente dans certaines anciennes versions PHP (<= 5.0?).

Exemple 2 . REQUEST_URI est différent de SCRIPT_NAME lorsqu'une chaîne de requête non vide est entrée:
http://example.com/test.php?foo=bar

[SCRIPT_NAME] => /test.php
[REQUEST_URI] => /test.php?foo=bar

Exemple 3 . REQUEST_URI est différent de SCRIPT_NAME lorsque la redirection côté serveur est active (par exemple, mod_rewrite sur Apache):

http://example.com/test.php

[REQUEST_URI] => /test.php
[SCRIPT_NAME] => /test2.php

Exemple 4 . REQUEST_URI est différent de SCRIPT_NAME lors de la gestion des erreurs HTTP avec des scripts.
Utilisation de la directive Apache ErrorDocument 404 /404error.php
http://example.com/test.php

[REQUEST_URI] => /test.php
[SCRIPT_NAME] => /404error.php

Sur le serveur IIS à l'aide de pages d'erreur personnalisées
http://example.com/test.php

[SCRIPT_NAME] => /404error.php
[REQUEST_URI] => /404error.php?404;http://example.com/test.php
214
Odin

PATH_INFO est uniquement disponible lorsque vous utilisez htaccess comme ceci:

Exemple 1

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]

Reste le même

[SCRIPT_NAME] => /index.php

Root

http://domain.com/

[PHP_SELF]     => /index.php
[PATH_INFO] IS NOT AVAILABLE (fallback to REQUEST_URI in your script)
[REQUEST_URI]  => /
[QUERY_STRING] => 

Chemin

http://domain.com/test

[PHP_SELF]     => /index.php/test
[PATH_INFO]    => /test
[REQUEST_URI]  => /test
[QUERY_STRING] => 

Chaîne de requête

http://domain.com/test?123

[PHP_SELF]     => /index.php/test
[PATH_INFO]    => /test
[REQUEST_URI]  => /test?123
[QUERY_STRING] => 123

Exemple 2

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]

Reste le même

[SCRIPT_NAME]  => /index.php
[PHP_SELF]     => /index.php
[PATH_INFO] IS NOT AVAILABLE (fallback to REQUEST_URI in your script)

Root

http://domain.com/

[REQUEST_URI]  => /
[QUERY_STRING] => 

Chemin

http://domain.com/test

[REQUEST_URI]  => /test
[QUERY_STRING] => url=test

Chaîne de requête

http://domain.com/test?123

[REQUEST_URI]  => /test?123
[QUERY_STRING] => url=test&123

Exemple 3

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(([a-z]{2})|(([a-z]{2})/)?(.*))$ index.php/$5 [NC,L,E=LANGUAGE:$2$4]

ou

RewriteRule ^([a-z]{2})(/(.*))?$ $3 [NC,L,E=LANGUAGE:$1]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]

Reste le même

[SCRIPT_NAME] => /index.php

Root

http://domain.com/

[PHP_SELF]          => /index.php
[PATH_INFO] IS NOT AVAILABLE (fallback to REQUEST_URI in your script)
[REQUEST_URI]       => /
[QUERY_STRING]      => 
[REDIRECT_LANGUAGE] IS NOT AVAILABLE

Chemin

http://domain.com/test

[PHP_SELF]          => /index.php/test
[PATH_INFO]         => /test
[REQUEST_URI]       => /test
[QUERY_STRING]      => 
[REDIRECT_LANGUAGE] => 

La langue

http://domain.com/fr

[PHP_SELF]          => /index.php/
[PATH_INFO]         => /
[REQUEST_URI]       => /en
[QUERY_STRING]      => 
[REDIRECT_LANGUAGE] => en

Chemin de la langue

http://domain.com/en/test

[PHP_SELF]          => /index.php/test
[PATH_INFO]         => /test
[REQUEST_URI]       => /en/test
[REDIRECT_LANGUAGE] => en

Chaîne de requête de langue

http://domain.com/fr/test?123

[PHP_SELF]          => /index.php/test
[PATH_INFO]         => /test
[REQUEST_URI]       => /en/test?123
[QUERY_STRING]      => 123
[REDIRECT_LANGUAGE] => en
19
Mike

Chemins PHP

  $_SERVER['REQUEST_URI']    = chemin Web, URI demandé
  $_SERVER['PHP_SELF']    = chemin Web, fichier demandé + informations sur le chemin
  $_SERVER['SCRIPT_NAME']    = chemin Web, fichier demandé
  $_SERVER['SCRIPT_FILENAME']   = chemin du fichier, fichier demandé
  __FILE__    = chemin du fichier, fichier actuel

  • Chemin du fichier est un chemin de fichier système comme /var/www/index.php, après la résolution d'un alias
  • chemin Web est un chemin de document serveur comme /index.php à partir de http://foo.com/index.php, et peut même ne correspondre à aucun fichier
  • Fichier actuel signifie le fichier de script inclus, pas n'importe quel script l'incluant
  • Fichier demandé signifie le fichier de script d'inclusion, pas celui inclus
  • URIest la requête HTTP comme /index.php?foo=bar, avant toute réécriture d'URL
  • Information de chemin est-ce que des données Apache supplémentaires sont situées après le nom du script mais avant la chaîne de requête

Ordre d'Opération

  1. Le client envoie au serveur une requête HTTPREQUEST_URI
  2. Le serveur effectue toute réécriture URL à partir de fichiers .htaccess, etc. pour obtenir PHP_SELF
  3. Le serveur sépare PHP_SELF en SCRIPT_FILENAME + PATH_INFO
  4. Le serveur effectue la résolution alias et convertit l'intégralité du chemin url en un chemin de fichier system pour obtenir SCRIPT_FILENAME
  5. Le fichier de script résultant peut en inclure d’autres, où __FILE__ fait référence au chemin du fichier actuel.
7
Beejor

Vous voudrez peut-être examiner la classe URI et utiliser $ this-> uri-> uri_string ()

Retourne une chaîne avec l'URI complet. 

Par exemple, s'il s'agit de votre URL complète:

http://example.com/index.php/news/local/345

La fonction renverrait ceci:

/news/local/345

Ou vous pouvez utiliser les segments pour explorer des zones spécifiques sans avoir à fournir des valeurs d'analyse/regex

4
Adam

Personnellement j'utilise le $REQUEST_URI car il fait référence à l'URI entré et non à l'emplacement sur le disque du serveur.

3
Xenph Yan

Il y a très peu de choses à ajouter à la réponse d'Odin. J'ai simplement eu le sentiment de fournir un exemple complet de la requête HTTP au fichier réel sur le système de fichiers pour illustrer les effets de la réécriture d'URL et des alias. Sur le système de fichiers, le script /var/www/test/php/script.php est

<?php
include ("script_included.php")
?>

/var/www/test/php/script_included.php est

<?php
echo "REQUEST_URI: " .  $_SERVER['REQUEST_URI'] . "<br>"; 
echo "PHP_SELF: " .  $_SERVER['PHP_SELF'] . "<br>";
echo "QUERY_STRING: " .  $_SERVER['QUERY_STRING'] . "<br>";
echo "SCRIPT_NAME: " .  $_SERVER['SCRIPT_NAME'] . "<br>";
echo "PATH_INFO: " .  $_SERVER['PATH_INFO'] . "<br>";
echo "SCRIPT_FILENAME: " . $_SERVER['SCRIPT_FILENAME'] . "<br>";
echo "__FILE__ : " . __FILE__ . "<br>";  
?>

et /var/www/test/.htaccess est

RewriteEngine On
RewriteRule before_rewrite/script.php/path/(.*) after_rewrite/script.php/path/$1 

et le fichier de configuration Apache comprend l'alias

Alias /test/after_rewrite/ /var/www/test/php/

et la requête http est 

www.example.com/test/before_rewrite/script.php/path/info?q=helloword

La sortie sera

REQUEST_URI: /test/before_rewrite/script.php/path/info?q=helloword
PHP_SELF: /test/after_rewrite/script.php/path/info
QUERY_STRING: q=helloword
SCRIPT_NAME: /test/after_rewrite/script.php
PATH_INFO: /path/info
SCRIPT_FILENAME: /var/www/test/php/script.php
__FILE__ : /var/www/test/php/script_included.php

Ce qui suit est toujours valable 

PHP_SELF = SCRIPT_NAME + PATH_INFO = full url path between domain and query string. 

S'il n'y a pas mod_rewrite, mod_dir, ErrorDocument rewrite ou toute forme de réécriture d'URL, nous avons également

REQUEST_URI = PHP_SELF + ? + QUERY_STRING 

Les alias affectent les chemins de fichiers système SCRIPT_FILENAME et __FILE__, pas les chemins d’URL définis précédemment - voir les exceptions ci-dessous. Les alias peuvent utiliser le chemin d'accès complet, y compris PATH_INFO. Il ne peut y avoir aucune connexion entre SCRIPT_NAME et SCRIPT_FILENAME

Il n'est pas tout à fait exact que les alias ne soient pas résolus au moment où le chemin d'URL [PHP_SELF] = [SCRIPT_NAME] + [PATH_INFO] est défini, car on considère que les alias effectuent une recherche dans le système de fichiers et nous savons d'après l'exemple 4 de la réponse d'Odin que le fichier est recherché pour déterminer l'existence du fichier , mais cela n’est pertinent que lorsque le fichier n’est pas trouvé. De même, mod_dir appelle mod_alias pour effectuer une recherche dans le système de fichiers, mais cela n’est pertinent que si vous avez un alias tel que Alias \index.php \var\www\index.php et que la requête uri est un répertoire. 

2
user2066805

Si vous oubliez quelles variables font quoi, vous pouvez écrire un petit script utilisant phpinfo () et l'appeler à partir d'une URL contenant une chaîne de requête. Comme les installations du logiciel serveur présentent les variables renvoyées par PHP, il est toujours judicieux de vérifier la sortie de la machine au cas où des réécritures dans le fichier de configuration du serveur donneraient des résultats différents de ceux attendus. Enregistrez-le sous la forme _inf0.php:

<?php
    $my_ip = '0.0.0.0';

   if($_SERVER['REMOTE_ADDR']==$my_ip){
     phpinfo();
   } else {
     //something
   }

Ensuite, vous appelez /_inf0.php?q=500

0
AbsoluteƵERØ