提问人:Basj 提问时间:10/22/2021 最后编辑:Basj 更新时间:11/16/2021 访问量:1234
如何使用 RewriteRule 以便为 PHP 修改 $_SERVER['REQUEST_URI']?
How to use RewriteRule such that $_SERVER['REQUEST_URI'] is modified too for 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的RewriteEngine也修改PHP将看到的REQUEST_URI
?
注意:我不想要 [R],因为重定向会生成新的浏览器请求,并更改 URL 栏中显示的 URL,这是我不想要的。
答:
经过进一步的研究,PHP 似乎总是会看到 RewriteRule 的原始 URL,而不是目标。(这里需要权威来源)。$_SERVER['REQUEST_URI']
顺便说一句,RewriteRule 的目标通常是处理请求的文件,除非我们使用 [R] 重定向标志,在这种情况下,浏览器将对新 URL 执行新请求(并且浏览器 URL 栏会更改)。
我认为如果没有一些解决方法,您尝试做的事情是不可能的。 我在这篇文章中提供了 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?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]
因此,以前的 .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 返回 Apache 而不是 .$_SERVER['REQUEST_URI']
original-uri
current-uri
使用此文件:.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”。CGIVar
REQUEST_URI
REDIRECT_URL
评论
$_SERVER["REDIRECT_URL"]
REQUEST_URI
重写后很有用,因为它可以让您访问原始的、不成文的 URL......无论是在 PHP 中还是在mod_rewrite规则中,例如 .最好不改变它。RewriteCond %{REQUEST_URI} \.php$ # user originally requested a php file