我有如下文件的层次结构:
/public_html/directory/
/public_html/directory/index.php
/public_html/directory/file.php
我想将请求转发到最合适的链接。例如,
mydomain.com/directory/
至mydomain.com/directory/index.php
mydomain.com/directory/file
至mydomain.com/directory/file.php
如果出现404或500错误,则将其转发给/public_html/error.php
为此,我在.htaccess
中编写了以下代码
Options +SymLinksIfOwnerMatch -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# don't touch /forum URIs
RewriteRule ^forums/ - [L,NC]
# hide .php extension snippet
#To externally redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}s([^.]+).php [NC]
RewriteRule ^ %1 [R,L]
# To internally forward /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
ErrorDocument 404 /error.php
ErrorDocument 500 /error.php
如果我如上所述提出请求,它会正常工作。但如果我请求页面mydomain.com/directory/file/scrap
,则它会生成Internal Server Error
我认为这是因为file
不是一个目录。但是我不知道如何解决这个问题。请提出建议。
最后,在服务器输出的关于500的ErrorDocument的错误中还提到了一行。完整的输出如下:
内部服务器错误
服务器遇到内部错误或配置错误无法完成您的请求。
请与服务器管理员联系,root@localhost并通知错误发生的时间,以及你可能做的任何事情这可能导致了错误。
服务器错误中可能提供了有关此错误的更多信息日志
此外,在尝试使用ErrorDocument来处理请求。
之所以会发生这种情况,是因为%{REQUEST_FILENAME} -f
条件还检查"路径信息"样式的请求。所以当你提出要求时:
mydomain.com/directory/file/scrap
重写引擎将看到文件/directory/file.php
,并假设您正在进行路径信息样式的请求,例如/directory/file.php/scrap
这会导致重写引擎循环。
您需要将该条件更改为:
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f
哦,至于ErrorDocument
的事情,我很确定发生的事情是重写模块完全结束了管道中的URL处理。这意味着,如果mod_rewrite翻转并结束所有处理,那么在管道的端应用的指令将永远不会被应用。这就是为什么没有应用ErrorDocument
指令的原因。如果您修复了重写问题,您会注意到500错误文档将再次工作。
根据上面的配置,我认为/error.php
有问题。
假设没有scrap.php
,mydomain.com/directory/file/scrap
将不会被重写。
500错误还提到,该错误是在尝试使用ErrorDocument时遇到的。
尝试使用静态error.html
而不是动态error.php
来缩小问题范围。
您也可以记录重写以验证它们是否正常工作:
RewriteLogLevel 9
RewriteLog /var/log/httpd/rewrite_log