РНР себя против пути против сценария имя против URI запроса


я создаю PHP-приложение в CodeIgniter. CodeIgniter отправляет все запросы на главный контроллер:index.php. Однако мне не нравится видеть index.php в URI. Например, http://www.example.com/faq/whatever будет маршрут к http://www.example.com/index.php/faq/whatever. Мне нужен надежный способ, чтобы скрипт знал, что это за адрес, поэтому он будет знать, что делать с навигацией. Я использовал mod_rewrite, согласно документации CodeIgniter.

правило таково:

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

обычно, я бы просто проверить php_self, но в этом случае это всегда index.php. Я могу получить его от REQUEST_URI,PATH_INFO и т. д. но я пытаюсь решить, что будет самым надежным. Кто-нибудь знает (или знает, где найти) реальную разницу между PHP_SELF,PATH_INFO,SCRIPT_NAME и REQUEST_URI? Спасибо за вашу помощь!

Примечание: мне пришлось добавить пробелы, так как так видит подчеркивание, и делает его курсивом по какой-то причине.

Обновлено: исправлены пробелы.

9 91

9 ответов:

The PHP документации могу сказать вам разницу:

'PHP_SELF'

имя текущего выполняемого скрипта, относительно корня документа. Например, $_SERVER ['PHP_SELF'] в скрипте по адресу http://example.com/test.php/foo.bar было бы /тест.php/foo.бар. Элемент _ _ FILE__ константа содержит полный путь и имя файла текущего (т. е. включенного) файла. Если PHP запущен в командной строке процессор, эта переменная содержит имя скрипта, начиная с PHP 4.3.0. Ранее он был недоступен.

'SCRIPT_NAME'

содержит путь к текущему сценарию. Это полезно для страниц, которые должны указывать на самих себя. Элемент _ _ FILE__ константа содержит полный путь и имя текущего (т. е. включен) файл.

'REQUEST_URI'

URI, который был дан для доступа к этой странице; например, ' / index.HTML-код'.

PATH_INFO, похоже, не документирован...

некоторые практические примеры различий между этими переменными:
Пример 1. PHP_SELF отличается от SCRIPT_NAME только когда запрошенный url находится в форме:
http://example.com/test.php/foo/bar

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

(это, кажется, единственный случай, когда PATH_INFO содержит разумную информацию [PATH_INFO] = > /foo / bar) Примечание: это было по-другому в некоторых старых версиях PHP (

Пример 2. REQUEST_URI-это отличается от SCRIPT_NAME при вводе непустой строки запроса:
http://example.com/test.php?foo=bar

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

Пример 3. REQUEST_URI отличается от SCRIPT_NAME, когда на стороне сервера действует перенаправление (например mod_rewrite на apache):

http://example.com/test.php

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

Пример 4. REQUEST_URI отличается от SCRIPT_NAME при обработке ошибок HTTP с помощью скриптов.
С использованием Apache директива ErrorDocument 404 /404error.php
http://example.com/test.php

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

на сервере IIS с использованием пользовательских страниц ошибок
http://example.com/test.php

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

PATH_INFO доступно только при использовании htaccess следующим образом:

Пример 1

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

остается одно и то же

[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] => 

путь

http://domain.com/test

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

Строку Запроса

http://domain.com/test?123

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

пример 2

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

остается одно и то же

[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] => 

путь

http://domain.com/test

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

Строку Запроса

http://domain.com/test?123

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

Пример 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/ [NC,L,E=LANGUAGE:]

или

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

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

остается то же самое

[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

путь

http://domain.com/test

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

язык

http://domain.com/en

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

путь к языку

http://domain.com/en/test

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

Язык Запросов строка

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

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

PHP пути

  $_SERVER['REQUEST_URI']    = веб-путь, запрошенный URI
    $_SERVER['PHP_SELF']    = веб-путь, запрошенный файл + информация о пути
    $_SERVER['SCRIPT_NAME']    = веб-путь, запрошенный файл
    $_SERVER['SCRIPT_FILENAME']   = путь к файлу, запрошенный файл
    __FILE__    = путь к файлу, текущий файл

здесь

  • путь к файлу это путь к системному файлу как /var/www/index.php, после разрешения псевдоним
  • путь - это путь к документу сервера как /index.php от http://foo.com/index.php, и может даже не совпадать ни с одним файлом
  • текущего файла означает включенный файл скрипта, не любой скрипт, который включает его
  • запрашиваемый файл означает в реестра, набрав файл скрипта, не включенный
  • URI - это HTTP-запроса как /index.php?foo=bar, перед любым URL переписывание
  • информация о пути любые дополнительные данные Apache, расположенные после имени скрипта, но перед строкой запроса

порядок работы

  1. клиент отправляет серверу HTTP-запросаREQUEST_URI
  2. сервер выполняет какие-либо переписывание URL из .файлы htaccess и др. чтобы получить PHP_SELF
  3. сервер выделяет PHP_SELF на SCRIPT_FILENAME + PATH_INFO
  4. сервер выполняет разрешение псевдоним и преобразует всю url path до путь к системному файлу и SCRIPT_FILENAME
  5. результирующий файл скрипта может включать другие, где __FILE__ ссылается на путь к текущему файлу

Вы можете посмотреть в разделе класс URI и использовать $this - > uri - >uri_string ()

возвращает строку с полным URI.

например, если это ваш полный URL:

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

функция будет возвращать этот:

/news/local/345

или вы можете использовать сегменты для детализации определенных областей без необходимости придумывать значения разбора / регулярных выражений

лично я использую $REQUEST_URI поскольку он ссылается на введенный URI, а не на местоположение на диске сервера.

есть очень мало, чтобы добавить к ответу Одина. Я просто хотел предоставить полный пример из HTTP-запроса в фактический файл в файловой системе, чтобы проиллюстрировать эффекты перезаписи URL и псевдонимов. В файловой системе скрипт /var/www/test/php/script.php и

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

здесь /var/www/test/php/script_included.php и

<?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>";  
?>

и /var/www/test/.htaccess и

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

и файл конфигурации Apache включает в себя псевдоним

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

и http-запрос

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

выход будет

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

всегда выполняется следующее

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

если нет mod_rewrite, mod_dir, ErrorDocument перезаписи или любой формы перезаписи URL, у нас также есть

REQUEST_URI = PHP_SELF + ? + QUERY_STRING 

псевдонимы влияют на пути к системным файлам SCRIPT_FILENAME и __FILE__, а не пути URL, которые определены ранее - см. исключения ниже. Псевдонимы могут использовать весь путь URL, включая PATH_INFO. Не может быть никакой связи между SCRIPT_NAME и SCRIPT_FILENAME .

не совсем точно, что псевдонимы не разрешаются во время пути URL [PHP_SELF] = [SCRIPT_NAME] + [PATH_INFO] определяется, потому что псевдонимы считаются для поиска файловой системы, и мы знаем из примера 4 в ответе Одина, что файловая система ищется, чтобы определить, существует ли файл, но это имеет значение только тогда, когда файл не найден. Аналогично, mod_dir вызывает mod_alias для поиска в файловой системе, но это актуально только в том случае, если у вас есть псевдоним, например Alias \index.php \var\www\index.php и uri запроса-это каталог.

Если вы когда-нибудь забудете, какие переменные делают что, вы можете написать небольшой скрипт, который использует phpinfo () и вызовите его из URL-адреса со строкой запроса. Поскольку установки серверного программного обеспечения представляют переменные, которые возвращает PHP, всегда рекомендуется проверять вывод машины в случае, если перезаписи в файле конфигурации сервера вызывают другие результаты, чем ожидалось. Сохраните его как что-то вроде _inf0.php:

<?php
    $my_ip = '0.0.0.0';

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

тогда вы бы позвонили /_inf0.php?q=500

резервное копирование на секунду, вы выбрали неправильный подход для начала. Почему бы просто не сделать это

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

вместо? Тогда хватай его с $_GET['url'];