如何使用重写规则,以便 $_SERVER['REQUEST_URI'] 也为 PHP 修改?



与此.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_URIREDIRECT_URL

经过进一步研究,PHP似乎总是会在$_SERVER['REQUEST_URI']中看到原始URL,而不是RewriteRule的目标。(此处需要权威来源)。

顺便说一下,RewriteRule的目标通常是一个将处理请求的文件,除非我们使用[R]重定向标志,那么在这种情况下,浏览器将对新的URL做一个新的请求(并且浏览器的URL栏会改变)。

相关内容

最新更新