113

我正在 CodeIgniter 中构建一个 PHP 应用程序。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 $1 !^(images|inc|favicon\.ico|index\.php|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L] 

通常,我会检查php_self,但在这种情况下,它总是index.php。我可以从 、 等处获得它REQUEST_URIPATH_INFO但我正在尝试确定哪个最可靠。有谁知道(或知道在哪里可以找到) 、 、 和 之间PHP_SELFPATH_INFO真正SCRIPT_NAME区别REQUEST_URI?谢谢你的帮助!

注意:我必须添加空格,因为 SO 看到下划线,并且出于某种原因将其设为斜体。

更新:修复了空格。

4

9 回答 9

246

这些变量之间差异的一些实际示例:
示例 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 不同(例如 apache 上的 mod_rewrite):

http://example.com/test.php

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

示例 4. 在使用脚本处理 HTTP 错误时,REQUEST_URI 与 SCRIPT_NAME 不同。
使用 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
于 2008-11-28T17:59:46.520 回答
54

PHP 文档可以告诉您区别:

'PHP_SELF'

当前执行脚本的文件名,相对于文档根目录。例如,地址http://example.com/test.php/foo.bar的脚本中的$_SERVER['PHP_SELF']将是/test.php/foo.bar__FILE__常量包含当前(即包含的)文件的完整路径和文件名。如果 PHP 作为命令行处理器运行,则此变量包含自 PHP 4.3.0 以来的脚本名称。以前它不可用。

'SCRIPT_NAME'

包含当前脚本的路径。这对于需要指向自身的页面很有用。__FILE__常量包含当前(即包含的)文件的完整路径和文件名。

'REQUEST_URI'

为访问此页面而提供的 URI;例如,'/index.html'

PATH_INFO 似乎没有记录...

于 2008-11-11T05:14:31.693 回答
25

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

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)

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

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
于 2012-03-07T11:22:58.917 回答
14

PHP 路径

  <code> $_SERVER['REQUEST_URI'] </code> = Web 路径,请求的 URI
  <code> $_SERVER['PHP_SELF'] </code> = Web 路径,请求的文件 + 路径信息
  <code> $_SERVER[' SCRIPT_NAME'] </code> = Web 路径,请求的文件
  <code> $_SERVER['SCRIPT_FILENAME'] </code> = 文件路径,请求的文件
  <code> __FILE__ </code> = 文件路径,当前文件
 </p >

在哪里

  • 文件路径系统文件路径,如/var/www/index.php别名解析后
  • Web 路径是类似于from 的服务器文档路径,甚至可能不匹配任何文件/index.phphttp://foo.com/index.php
  • 当前文件是指包含的脚本文件,而不是包含它的任何脚本
  • 请求的文件是指包含脚本文件,而不是包含的文件
  • URI是在任何 URL 重写之前的HTTP 请求/index.php?foo=bar
  • 路径信息是位于脚本名称之后但查询字符串之前的任何额外的 Apache 数据

操作顺序

  1. 客户端向服务器发送HTTP 请求 REQUEST_URI
  2. 服务器从 .htaccess 文件等执行任何URL 重写以获取PHP_SELF
  3. 服务器PHP_SELF分为SCRIPT_FILENAME+PATH_INFO
  4. 服务端进行别名解析,将整个url路径转换为系统文件路径获取SCRIPT_FILENAME
  5. 生成的脚本文件可能包含其他文件,其中__FILE__指的是当前文件的路径
于 2015-04-10T05:12:47.867 回答
5

您可能想查看URI 类并使用 $this->uri->uri_string()

返回具有完整 URI 的字符串。

例如,如果这是您的完整 URL:

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

该函数将返回:

/news/local/345

或者您可以利用这些段来深入了解特定区域,而无需提出解析/正则表达式值

于 2008-11-11T05:09:02.250 回答
4

我个人使用它,$REQUEST_URI因为它引用输入的 URI,而不是服务器磁盘上的位置。

于 2008-11-11T04:17:09.733 回答
4

奥丁的答案几乎没有什么可补充的。我只是觉得提供一个从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/$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] ,因为别名被认为是搜索文件系统,我们从 Odin 回答中的示例 4 中知道,搜索文件系统以确定文件是否存在,但这仅在找不到文件时才有意义。类似地,mod_dir 调用 mod_alias 来搜索文件系统,但这仅在您有别名Alias \index.php \var\www\index.php且请求 uri 是目录时才相关。

于 2015-12-16T04:34:11.947 回答
1

如果您忘记了哪些变量做了什么,您可以编写一个使用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

于 2018-07-23T14:46:16.993 回答
-1

备份一秒钟,您一开始就采取了错误的方法。为什么不这样做

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

反而?然后抓住它$_GET['url'];

于 2008-12-28T02:00:57.560 回答