RewriteRule用于页面处理,提供目标页面名称而不是请求

时间:2017-11-16 04:37:29

标签: php apache .htaccess mod-rewrite

我有这段代码:

RewriteEngine on
RewriteRule api/v2/([^/]+)/?$ api/v2/api.php?request=$1 [L]
RewriteRule api/v2 api/v2/api.php [L]
RewriteRule ^$ handler.php?request=main [L]
RewriteRule ^(.*)$ handler.php?request=$1 [L]


...在根目录下的.htaccess文件中。其目的是用https://example.org/hello/world重写https://example.org/handler.php?request=hello/world

每当我导航到现有目录时,它都会在末尾添加?request。例如:如果我导航到https://example.org/foo(foo是目录),它将重定向到https://example.org/foo/?request=foo

为什么会发生这种情况,我该如何解决?

更新1
我添加了以下几行,它们可以根据需要使用:

RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]

但这引起了另一个问题,当我去handler.php和echo $_GET["request"]时,我得到handler.php

更新2
我已将.htaccess简化为此:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
RewriteRule ^(.*)$ handler.php?request=$1 [L]

但仍有同样的问题,$_GET["request"]会返回handler.php

更新3
我为这个问题增加了一笔赏金,更多的是出于好奇而不是现在的任何事情。

2 个答案:

答案 0 :(得分:1)

我会以相反的方式使用它。 如果请求的文件不是,则现有文件或目录然后会根据请求将重写文件设置为处理程序文件。

测试了以下代码,似乎可以正常工作。

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ handler.php?request=$1 [L]
</IfModule>

<强> handler.php

var_dump($_GET);

http://localhost/hello/world

输出:

array(1) { ["request"]=> string(11) "hello/world" }

http://localhost/example(确实存在)

输出:

Directory parent

http://localhost/a.php(确实存在)

输出:

File a exists //Something that is written in a.php

答案 1 :(得分:1)

问题在于您的规则是以循环模式重写请求,因为无条件规则和catch-all模式将目标文件 handler.php 重写为自身。

您需要修复规则的模式,使其与目标文件不匹配。

rewrite engine on
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
RewriteRule ^((?!handler.php).*)$ handler.php?request=$1 [L]