如何使用 RewriteRule 以便为 PHP 修改 $_SERVER['REQUEST_URI']?

How to use RewriteRule such that $_SERVER['REQUEST_URI'] is modified too for PHP?

提问人:Basj 提问时间:10/22/2021 最后编辑:Basj 更新时间:11/16/2021 访问量:1234

问:

有了这个:.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的RewriteEngine也修改PHP将看到的REQUEST_URI

注意:我不想要 [R],因为重定向会生成新的浏览器请求,并更改 URL 栏中显示的 URL,这是我不想要的。

另请参阅 RewriteRule,当替换字符串不是文件路径,而是应由下一个规则处理的 URL

php .htaccess mod-rewrite url-rewriting request-uri

评论

2赞 CBroe 10/22/2021
我不确定有没有办法做到这一点,只能从Apache端。stackoverflow.com/a/18618316/1427878,这是一个类似的主题 - 但建议的解决方案是寻找之后的价值,这可能对你没有多大帮助,因为我假设你仍然在你之前的上下文中问这个问题, WordPress 相关的问题 stackoverflow.com/q/69662962/1427878$_SERVER["REDIRECT_URL"]
1赞 Salman A 11/11/2021
REQUEST_URI重写后很有用,因为它可以让您访问原始的、不成文的 URL......无论是在 PHP 中还是在mod_rewrite规则中,例如 .最好不改变它。RewriteCond %{REQUEST_URI} \.php$ # user originally requested a php file

答:

0赞 Basj 11/10/2021 #1

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

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

2赞 Douma 11/11/2021 #2

我认为如果没有一些解决方法,您尝试做的事情是不可能的。 我在这篇文章中提供了 2 种解决方案,一种使用 auto_prepend_file,一种使用 mod_proxy。

解决方案 1:使用 auto_prepend_file

请看下面的脚本,它并没有直接将REQUEST_URI设置为全局,而是用以下代码在PHP中覆盖它:

.ht访问

php_value auto_prepend_file "before.php" 

RewriteEngine On
RewriteRule foo/(.*) /foo-$1
RewriteRule . index.php [L]

请务必添加以下行:

php_value auto_prepend_file "before.php" 

之前 .php

在此脚本中,您可以替换以下REQUEST_URI:

喜欢:

$_SERVER['REQUEST_URI'] = "/" . str_replace('/', '-', ltrim($_SERVER['REQUEST_URI'], "/"));

你可以进一步改进这个脚本,但我认为这个概念很清楚。

索引:.php

Index.php 不受影响,但包含重写的规则:

var_dump($_SERVER['REQUEST_URI']); //string(7) "/foo-bar"

现在的请求是:http://localhost/foo/bar?teststring(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]

因此,以前的 .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 预置文件是一种更有效的方法。

1赞 JMP 11/16/2021 #3

PHP 返回 Apache 而不是 .$_SERVER['REQUEST_URI']original-uricurrent-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" 

如果没有该行,它将为 和 提供“/hello/world”。CGIVarREQUEST_URIREDIRECT_URL