Php 重写htaccess规则无法完美运行

Php 重写htaccess规则无法完美运行,php,.htaccess,Php,.htaccess,我有一系列不同类别的规则,这里有一个类别 RewriteRule ^words/$ /words/publicWordLists.php [L] RewriteRule ^words/([A-Za-z]+$) /words/word.php?word=$1 [L] RewriteRule ^([A-Za-z0-9-]+)/words/$ /words/userWordLists.php?username=$1 [L] RewriteRule ^([A-Za-z0-9-]+)/words/([A-

我有一系列不同类别的规则,这里有一个类别

RewriteRule ^words/$ /words/publicWordLists.php [L]
RewriteRule ^words/([A-Za-z]+$) /words/word.php?word=$1 [L]
RewriteRule ^([A-Za-z0-9-]+)/words/$ /words/userWordLists.php?username=$1 [L]
RewriteRule ^([A-Za-z0-9-]+)/words/([A-Za-z0-9-]+$) /words/list.php?username=$1&url=$2 [L]
这非常有效,因为如果您转到words/您从publicWordsList.php获取内容-但是-如果您直接转到/words/publicWordList.php-它不会重定向回words/

那么,如何防止人们直接访问这些页面,同时仍然保持我最初的意图呢?

您可以在文件顶部创建一个“重定向”,301将从“丑陋”的文件系统路径重定向到所需的URL。但是,您需要小心重定向循环,因为稍后的重写会再次重写URL

例如:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^words/publicWordLists\.php$ /words/ [R=302,L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^word=([a-zA-Z]+)$
RewriteRule ^words/word\.php$ /words/%1 [QSD,R=302,L]
对环境变量
REDIRECT\u STATUS
的检查可防止重定向循环,因为它只查看初始请求,而不查看重写的请求<代码>重定向_状态最初为空,但在第一次成功重写后设置为“200”

只有在确认一切正常后才能将
302
(临时)更改为
301
(永久),以避免潜在的缓存问题

包含查询字符串的其他指令有点棘手,因为它们需要附加条件。查询字符串不是由
RewriteRule
模式匹配的URL路径的一部分

例如:

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^words/publicWordLists\.php$ /words/ [R=302,L]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^word=([a-zA-Z]+)$
RewriteRule ^words/word\.php$ /words/%1 [QSD,R=302,L]
上面将
/word/word.php?word=
重定向到
/words/

%1
是对前面的
RewriteCond
指令中捕获的URL参数值的反向引用。
QSD
标志是从重定向请求中删除原始查询字符串所必需的

更新:QSD标志是Apache 2.4+。如果您仍然使用Apache2.2,那么您可以在替换字符串(本质上是一个空查询字符串)的末尾追加一个
,以便从重定向的URL中删除查询字符串。例如,在Apache2.2上,您将需要以下内容:

RewriteRule ^words/word\.php$ /words/%1? [R=302,L]

创建一个函数并重定向到正确的URL版本:到目前为止,这几乎可以完美地工作,我非常感谢您的专家帮助。第一个完全按照描述工作。但是在带有查询字符串的重定向中,QSD导致整个站点出现内部服务错误。如果我取出QSD,它会按照您的建议执行(正确重定向,但不会删除查询字符串)。想法?你使用的是什么版本的Apache?
QSD
标志是Apache2.4+。在Apache2.2上,您需要附加一个空的查询字符串。我已经更新了我的答案。你是对的,我使用的是Apache2.2。真棒的帮助,再次感谢!