我认为如果没有一些工作,你尝试做的事情是不可能的。我在这篇文章中提供了两种解决方案,一种使用 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"
之前的.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]
因此 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 前置文件是一种更有效的方式。