【问题标题】:Why is the URL parameter value equal to "index.php"?为什么 URL 参数值等于“index.php”?
【发布时间】:2015-02-06 06:46:57
【问题描述】:

我正在将 mod_rewrite 与 Apache 和 PHP 一起使用来重写页面的 URL。
对于网站上的一页,我使用以下内容,效果很好:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteRule ^(\d+)/? index.php?id=$1
</IfModule>

但是,对于网站上的另一个页面(我遇到问题的那个),我正在使用以下内容:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteRule ^(\w+)/? index.php?id=$1
</IfModule>

基本上,\d 更改为 \w
出于某种原因,对于\w 页面,id 参数被设置为index,而不是 URL 中的实际值。 如果我将\w 更改为.,则id 参数等于index.php

当我查看 PHP $_SERVER 超全局时,REDIRECT_QUERY_STRING 参数设置正确,但 QUERY_STRING 参数设置为 indexindex.php(取决于我使用的是 \w 还是.)。

这里发生了什么,为什么?
更重要的是,我该如何解决这个问题?
谢谢。

【问题讨论】:

  • 你期望它是什么? \w 将匹配任何单词字符,因此它不会捕获 .php 部分,而 . 匹配任何字符,因此会完整捕获 index.php
  • \w = "单词字符",基本上是a-zA-Z. 不是其中之一。执行^(\w) 将从index.php 中捕获index,因为. 被明确排除在\w 之外。

标签: php apache .htaccess mod-rewrite query-string


【解决方案1】:

这是因为您的规则不止一次执行,因为您的模式只是 ^(\w+)/? 没有锚点 $

您可以通过在该规则之前添加RewriteCond 来修复它:

<IfModule mod_rewrite.c>
  RewriteEngine On

    # If the request is not for a valid directory
    RewriteCond %{REQUEST_FILENAME} !-d
    # If the request is not for a valid file
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.+?)/?$ index.php?id=$1 [L,QSA]
</IfModule>

【讨论】:

  • 你是对的!哇!我所要做的就是在/? 之后添加一个$ 以使其正常工作。为什么规则在没有结束锚点的情况下多次执行?
  • 当您拥有^(\w+)/? 时,它首先匹配原始URI /something。它被重写为/index.php?id=something。现在mod_rewrite 在循环中运行,因此它将^(\w+)/? 模式应用于/index.php,并且由于它匹配/index,因此将其重写为/index.php?id=index。由于原始 URI 和重写的 URI 相同,因此它在此停止。但也要记住,如果你使用模式^(.+?)/?$,那么你必须使用RewriteCond,就像我展示的那样来防止这种行为。
  • 非常感谢您的解释。它有很大帮助。我最终使用了^([A-Za-z0-9-]+)/?$,它在没有条件的情况下工作得很好。
  • 可以的。但是请记住,它也会将现有目录写入index.php
  • 是的,好点。我想解决方案是在任何子文件夹中都有另一个 .htaccess 文件,对吧?或者,当然,我也可以使用您建议的条件。
猜你喜欢
  • 2018-04-03
  • 2014-01-22
  • 2021-05-08
  • 1970-01-01
  • 2011-12-13
  • 1970-01-01
  • 1970-01-01
  • 2016-12-10
  • 2023-03-22
相关资源
最近更新 更多