我注意到htaccess中的[OR]问题我不明白。我想要做的是将每个不存在的文件和每个.php文件(而不是/index.php)的文件重定向到/ 404 /。根据我的理解,下面两个块应该做同样的事情:
# .htaccess 1
RewriteEngine on
# cond 1
RewriteCond %{REQUEST_FILENAME} !-f [OR]
# cond 2
RewriteCond %{REQUEST_FILENAME} !index\.php$
# cond 3
RewriteCond %{REQUEST_URI} \.php$
# rule 1
RewriteRule [^\.]*\.[a-zA-Z0-9]+$ /404/ [L]
# rule 2
RewriteRule ^(([^/\.]+)/?)*?$ /index.php [L]
和此:
# .htaccess 2
RewriteEngine on
# cond 1
RewriteCond %{REQUEST_FILENAME} !-f
# rule 1
RewriteRule [^\.]*\.[a-zA-Z0-9]+$ /404/ [L]
# cond 2
RewriteCond %{REQUEST_FILENAME} !index\.php$
# cond 3
RewriteCond %{REQUEST_URI} \.php$
# rule 2
RewriteRule [^\.]*\.[a-zA-Z0-9]+$ /404/ [L]
# rule 3
RewriteRule ^(([^/\.]+)/?)*?$ /index.php [L]
然而,只有第二个区块能够满足我的需求。例如,第一个.htaccess - 无法重定向不存在的文件a.pdf,而是显示有关未找到文件的默认服务器消息。
有人可以向我解释一下吗?
答案 0 :(得分:2)
你在第一个.htaccess中的OR条件的顺序错误。
[OR]
标志围绕两个语句创建一个组,有效地将条件写为:
if (
(FILE_NOT_FOUND or FILE_NAME === 'index.php')
and REQUEST_URI ends in .php
) { ... }
按此顺序编写,条件将永远不会匹配以扩展名其他结尾的URI而不是PHP。
你真正想要的是:
if (
(FILE_NOT_FOUND or REQUEST_URI ends in .php)
and FILE_NAME !== 'index.php'
) { ... }
可以通过简单地重新排列两个相关的重写条件来表达:
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} \.php$
RewriteCond %{REQUEST_URI} !index\.php
RewriteRule [^\.]*\.[a-zA-Z0-9]+$ /404/ [L]
你甚至可以通过阅读自己的单词来解决你的错误(简化以显示你想到的实际条件):
我想要做的是重定向每个不存在的文件 [或] 每个.php文件,[和] 不是/index.php 到/ 404 /.
Here is a good StackOverflow question/answer关于[OR]
在.htaccess文件中的优先顺序,如果您想了解更多关于mod_rewrite如何在内部实际运作的信息。