为什么这个RewriteRule改变QUERY_STRING,但保持REQUEST_URI不变?

Pek*_*ica 8 apache .htaccess mod-rewrite url-rewriting concrete5

我有一个Concrete5的副本,这是一个基于PHP的CMS,正在运行example.com.

Concrete5附带了以下关于漂亮URL的基本说明(将所有URL重定向到中心index.php)

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/c5.7
RewriteRule ^.*$ c5.7/$0 [L]    # Concrete5 is running in the c5.7/ subdirectory
</IfModule>
Run Code Online (Sandbox Code Playgroud)

非常直截了当.

现在我有一组接受表单的URL

 /product/{productname}
Run Code Online (Sandbox Code Playgroud)

我需要转发到Concrete5(虚拟)URL

/products/details?name={productname}
Run Code Online (Sandbox Code Playgroud)

当我在浏览器中手动输入时,该URL已设置并按预期工作.

所以我在htaccess文件中添加了一行,现在看起来像这样:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

# New rule for products
RewriteCond %{REQUEST_URI} ^/product/
RewriteRule ^product/(.+)$ /products/details?name=$1 [QSA]

RewriteCond %{REQUEST_URI} !^/c5.7
RewriteRule ^.*$ c5.7/$0 [L]

</IfModule>
Run Code Online (Sandbox Code Playgroud)

RewriteRule当我选择随机外部URL作为重定向目标时,我可以确认触发了.

但无论何时它是如上所述的内部重定向,会发生什么,我在Concrete5中得到404.当我检查传递给它的内容时,我看到:

 REQUEST_URI:  /product/my-random-product
 QUERY_STRING: name=my-random-product
Run Code Online (Sandbox Code Playgroud)

因此看起来规则被触发并进行一些重写,但REQUEST_URI保持不变!

为什么?

是因为PHP 7.1是通过CGI运行的吗?

我尝试了很多变化和书中的所有标志,但收效甚微.

LSe*_*rni 1

您的设置适用于 PHP 7.1 机器(没有 Concrete5)。它确实调用了我刚刚放入的脚本,该脚本位于 /c5.7/products/details 中。所以 Apache 部分正在工作。

在脚本中,我看到这REQUEST_URI是重写之前的旧值。

所以它的值是正常的,不被重写是一个转移注意力的事情——它不应该被重写。404 错误肯定是由于其他原因造成的。

你的 Concrete5 路由应该支持真实的 URL,而不仅仅是虚拟的 URL,因为 C5 的路由本身依赖于 REQUEST_URI。如果是这样,您需要为您的短网址创建一个路由

Route::register('/product/{productname}' ...)
Run Code Online (Sandbox Code Playgroud)

以及一个适当的控制器来获取参数并调用“旧”控制器。

使用 .htaccess 的一种可能性可能是这样,但我不太确定它是否有效,因为 REQUEST_URI 仍然保持不变:

# New rule for products
RewriteCond %{REQUEST_URI} ^/product/
RewriteRule ^product/(.+)$ c5.7/products/details?name=$1 [L,QSA]
Run Code Online (Sandbox Code Playgroud)

否则,您需要执行外部重定向,这将在浏览器中公开 URL:

RewriteRule product/(.*)$ http://.../products/details?name=$1 [QSA]
Run Code Online (Sandbox Code Playgroud)

另请参阅另一个问题