与此.htaccess
:
RewriteEngine On
RewriteRule foo/(.*) /foo-$1 # here I tried [L], [PT], [C], etc.
RewriteRule . index.php [L]
我已经尝试了所有可能的标志为第一个RewriteRule,但总是,这段PHP代码:
<?php echo $_SERVER['REQUEST_URI']; ?>
当访问http://example.com/foo/bar时,总是返回/foo/bar
而不是/foo-bar
。为什么?
如何让Apache的重写引擎也修改REQUEST_URI
,将由PHP看到?
注意:我不想要[R],因为重定向会生成一个新的浏览器请求,并改变URL栏中显示的URL,这是我不想要的。
当替换字符串不是文件路径而是一个URL时,请参见RewriteRule,该URL应该由下一个规则处理。
我认为你要做的事情是不可能的,没有一些工作。我在这篇文章中提供了两个解决方案,一个使用auto_prepend_file,一个使用mod_proxy。
解决方案1:使用auto_prepend_file请查看下面的脚本,这并没有直接设置REQUEST_URI全局,而是在PHP中覆盖它,使用以下代码:
. htaccess
php_value auto_prepend_file "before.php"
RewriteEngine On
RewriteRule foo/(.*) /foo-$1
RewriteRule . index.php [L]
一定要加上这一行:
php_value auto_prepend_file "before.php"
before.php
在这个脚本中你可以替换REQUEST_URI:
:
$_SERVER['REQUEST_URI'] = "/" . str_replace('/', '-', ltrim($_SERVER['REQUEST_URI'], "/"));
你可以进一步改进这个脚本,但我认为这个概念是明确的。
index . php
Index.php不受影响,但包含重写的规则:
var_dump($_SERVER['REQUEST_URI']); //string(7) "/foo-bar"
对http://localhost/foo/bar?test
的请求现在是:string(13) "/foo-bar?test"
更新当使用[L]时,您可以通过以下方式获得重写的url:
var_dump($_SERVER['REDIRECT_URL']); # /foo-bar
所以。htaccess变成了:
php_value auto_prepend_file "before.php"
RewriteEngine On
RewriteRule foo/(.*) /foo-$1 [L] # please note [L] here
RewriteRule . index.php [L]
因此before.php可以替换为:
$_SERVER['REQUEST_URI'] = $_SERVER['REDIRECT_URL'];
更新方案2;使用mod_proxy
发现你也可以使用mod代理:
我必须启用以下模块:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
现在你的。htaccess被改成(注意[p]标志):
RewriteEngine On
RewriteRule ^foo/(.+)$ /foo-$1 [L,P]
RewriteRule . index.php
这将代理所有foo/bar请求到/foo-bar,并相应地更改$_SERVER['REQUEST_URI']
。
var_dump($_SERVER['REQUEST_URI']); //output: string(8) "/foo-bar"
我认为使用PHP前置文件是一个更有效的方法。
PHP的$_SERVER['REQUEST_URI']
返回Apache的original-uri
而不是current-uri
。
CGIVar指令
使用.htaccess
文件:
CGIVar REQUEST_URI current-uri
RewriteRule (.*) index.php [L]
则请求example.com/hello/world
将给出:
$_SERVER["REQUEST_URI"] "/index.php"
$_SERVER["REDIRECT_URL"] "/hello/world"
如果没有CGIVar
行,它将显示"/hello/world"REQUEST_URI
和REDIRECT_URL
,
经过进一步研究,PHP似乎总是会在$_SERVER['REQUEST_URI']
中看到原始URL,而不是RewriteRule的目标。(此处需要权威来源)。