PHP_SELF vs PATH_INFO против SCRIPT_NAME и REQUEST_URI
Я создаю PHP-приложение в CodeIgniter. CodeIgniter отправляет все запросы на главный контроллер: index.php
. Тем не менее, я не люблю видеть index.php
в URI. Например, http://www.example.com/faq/whatever
будет маршрутизироваться в http://www.example.com/index.php/faq/whatever
. Мне нужен надежный способ для script знать, что это за адрес, поэтому он будет знать, что делать с навигацией. Я использовал mod_rewrite
в соответствии с документацией CodeIgniter.
Правило выглядит следующим образом:
RewriteEngine on
RewriteCond $1 !^(images|inc|favicon\.ico|index\.php|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
Обычно я просто проверяю php_self
, но в этом случае он всегда index.php
. Я могу получить его от REQUEST_URI
, PATH_INFO
и т.д., Но я пытаюсь решить, какой из них будет наиболее надежным. Кто-нибудь знает (или знает, где найти) реальную разницу между php_self
, PATH_INFO
, SCRIPT_NAME
и REQUEST_URI
? Спасибо за вашу помощь!
Примечание. Мне пришлось добавлять пробелы, так как SO видит символ подчеркивания и по какой-то причине делает его курсивом.
Обновлено. Исправлены пробелы.
Ответы
Ответ 1
документация по PHP может сказать вам разницу:
<я > 'PHP_SELF'
Имя исполняемого файла script, относящегося к корню документа. Например, $_ SERVER ['PHP_SELF'] в script по адресу http://example.com/test.php/foo.bar будет /test.php/foo.bar. Константа __ FILE__ содержит полный путь и имя файла текущего (то есть включенного) файла. Если PHP работает как процессор командной строки, эта переменная содержит имя script с PHP 4.3.0. Раньше он не был доступен.
<я > 'SCRIPT_NAME
Содержит текущий путь script. Это полезно для страниц, которые должны указывать на себя. Константа __ FILE__ содержит полный путь и имя файла текущего (например, включенного) файла.
<я > 'REQUEST_URI'
URI, который был предоставлен для доступа к этой странице; например, '/index.html'.
PATH_INFO, похоже, не документирован...
Ответ 2
Некоторые практические примеры различий между этими переменными:
Пример 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 (< = 5.0?) Это отличалось.
Пример 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
Ответ 3
PATH_INFO
доступен только при использовании htaccess:
Пример 1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [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=$1 [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/$5 [NC,L,E=LANGUAGE:$2$4]
или
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]
Остается тот же
[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
Ответ 4
Пути 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
и может даже не соответствовать любому файлу
- Текущий файл означает включенный script файл, а не script, который включает его
- Запрашиваемый файл означает файл include script, а не включенный
- URI - это HTTP-запрос, например
/index.php?foo=bar
, перед переписыванием URL
- Информация о пути - это любые дополнительные данные Apache, расположенные после имени script, но перед строкой запроса
Порядок работы
- Клиент отправляет сервер HTTP-запрос
REQUEST_URI
- Сервер выполняет любую переписывание URL из файлов .htaccess и т.д., чтобы получить
PHP_SELF
- Сервер разделяет
PHP_SELF
на SCRIPT_FILENAME
+ PATH_INFO
- Сервер выполняет разрешение псевдонима и преобразует весь URL-адрес в путь к системному файлу, чтобы получить
SCRIPT_FILENAME
- Результирующий script файл может содержать другие, где
__FILE__
ссылается на путь к текущему файлу
Ответ 5
Вы можете посмотреть в URI Class и использовать $this- > uri- > uri_string()
Возвращает строку с полным URI.
Например, если это ваш полный URL-адрес:
http://example.com/index.php/news/local/345
Функция вернет это:
/news/local/345
Или вы можете использовать сегменты для развертки определенных областей, не прибегая к значениям синтаксического анализа/регулярного выражения
Ответ 6
Лично я использую $REQUEST_URI
, поскольку он ссылается на введенный URI, а не на место на диске сервера.
Ответ 7
В ответ Odin очень мало добавить. Я просто хотел представить полный пример из HTTP-запроса в фактический файл в файловой системе, чтобы проиллюстрировать последствия перезаписи URL-адресов и псевдонимов. В файловой системе script /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/$1
а файл конфигурации 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 запроса - это каталог.
Ответ 8
Резервное копирование в секунду, с самого начала вы использовали неправильный подход. Почему бы просто не сделать это
RewriteEngine on
RewriteCond $1 !^(images|inc|favicon\.ico|index\.php|robots\.txt)
RewriteRule ^(.*)$ /index.php?url=$1 [L]
вместо этого? Затем возьмите его с помощью $_GET['url'];