【发布时间】:2012-06-17 23:44:35
【问题描述】:
我正在尝试做很多人以前做过很多次的事情,但我似乎无法让它发挥作用。我已经尝试了将近 2 天,我一直在互联网上搜索一个工作示例,发现了许多非常相似的 SO 问题,但没有一个对我有用 - 其中大多数都在使用键/值方法,我只是想要值列表。
我想要什么:
我希望能够使用搜索引擎友好的 URL。由于相关站点当前工作方式的性质,我想转换此请求 URI:
/this/is/a/随机/路径...到:
/index.php?p[]=this&p[]=is&p[]=a&p[]=random&p[]=path这样当它到达 PHP 时,它将作为索引数组在$_GET['p'] 中可用。我也希望它也能容忍斜杠,所以我会得到相同的结果:
我是如何尝试的:
我对正则表达式并没有太不好,而且我对 mod_rewrite 的工作原理有合理的理解,但我认为我已经消失在错误的道路上,以至于我再也看不到回去的路了。
这是我目前拥有的:
# 打开 mod_rewrite 重写引擎开启 # 允许直接加载 /static 目录中的文件 RewriteCond %{REQUEST_FILENAME} -f 重写规则 ^/?static/(.+)$ - [L] # 递归捕获所有路径组件 RewriteCond %{REQUEST_URI} !^/?(?:index\.php)?$ 重写规则 ^/?([^/]+)(?:/(.+)$|/?$) $2?p[]=$1 [QSA,L] # 向控制器发送请求 重写规则 ^.*$ index.php [QSA]怎么了:
第一个 RewriteCond/RewriteRule 对运行良好 - 如果我请求存在于 /static 目录中的文件,则请求保持原样并提供文件。如果文件不存在,它会进入第二组规则,这样我就可以显示我的一个性感的基于 PHP 的错误页面。
问题在于第二个RewriteCond/RewriteRule 对,也可能是第三个RewriteRule。该条件应该存在以确保最终迭代不会导致将脚本名称添加到数组中-这似乎可行。这是我认为第二个RewriteRule 正在做的事情,我怀疑我在这里错过了一些明显的东西:
这是 90% 的工作。我遇到的问题:
- 数组组件的顺序颠倒了。我理解为什么会这样,并且我意识到这可能是不可避免的,使用
array_reverse()在 PHP 中很容易解决。我只提到它以防有人能想到我想不到的 mod_rewrite 解决方案。 -
最后两个位置的重复路径组件会导致失败。例如,如果我请求
/home/home或/some/path/path,我会得到一个标准的 Apache 404,指出未找到最后两个路径组件(上面两个示例中的/home/home和/path/path)。 但是如果我在末尾添加另一个路径组件,例如/home/home/something,那么它会再次起作用。我无法理解造成这种情况的原因。
谁能解释为什么会发生这种情况,或者提出更好的方法来做到这一点?
【问题讨论】:
-
你绝对必须在 htaccess 中做到这一点,或者你不能仅仅在 PHP 中
$_SERVER['REQUEST_URI']的斜线周围爆炸吗? -
@NevStokes 你能详细说明一下吗?主要是关于我如何确保所有请求都以
index.php结尾,同时仍然允许引用存在的文件的/staticURI 不受影响?如果可以使它起作用,这听起来确实是一个有吸引力的选择-因为它不受LimitInternalRecursion/MaxRedirects限制。 -
你为什么不在你的 PHP 脚本中这样做呢?
/index.php?p=/this/is/a/random/path -
@Qtax 我开始认为我的
but I think I have disappeared so far up the wrong road that I can no longer see the way back声明可能比我想象的更真实!我现在只是在玩它,我想这就是答案。
标签: regex .htaccess mod-rewrite recursion url-rewriting