为何.htaccess的Files指令仅在目标文件所在目录配置时才生效?
为何.htaccess的Files指令仅在目标文件所在目录配置时才生效?
兄弟,我太懂你这种踩坑的感觉了!其实问题出在<Files>指令的核心匹配逻辑上,跟你用的是Require还是旧的Order Allow,Deny规则没关系,具体原因和解决方法我给你掰扯清楚:
核心问题:<Files>指令只认当前目录下的文件名,不认路径
<Files>指令的设计就是仅匹配当前.htaccess文件所在目录下的具体文件名,它完全不支持带路径的写法——不管是相对路径(比如你写的folder/specific.php)还是绝对路径,在它眼里都是一个完整的文件名,而不是“某个子文件夹里的文件”。
那你之前的操作为什么行不通?我拆解给你看:
- 根目录的
.htaccess里写<Files "*.php"> Require all denied </Files>是没问题的,它会作用于根目录及其所有子目录的PHP文件(除非子目录有自己的.htaccess覆盖这个规则)。 - 你在
subdir目录的.htaccess里写<Files "folder/specific.php">,这条规则其实是在找subdir目录下一个名叫folder/specific.php的文件(而不是subdir/folder/里的specific.php),显然这个文件不存在,所以这条规则等于没生效,根目录的拒绝规则依然会生效。 - 而你把
<Files "*.php"> Require all granted </Files>直接放到subdir/folder/目录下时,这个.htaccess作用于当前目录,<Files>匹配的是该目录下的PHP文件,自然specific.php就被允许访问了,根目录的规则被成功覆盖。
给你几个正确的解决思路
精准匹配单个文件(推荐)
直接在subdir/folder/目录下的.htaccess里写:<Files "specific.php"> Require all granted </Files>比写
*.php更安全,只放开你需要的那个文件。在根目录用
<FilesMatch>实现全局规则
如果不想在子目录单独放.htaccess,可以在根目录用支持正则匹配的<FilesMatch>,它能匹配相对于根目录的完整请求路径:# 先拒绝所有PHP文件 <Files "*.php"> Require all denied </Files> # 再单独放开指定文件 <FilesMatch "^subdir/folder/specific\.php$"> Require all granted </FilesMatch>注意正则里要转义
.,而且路径是相对于网站根目录的。用主配置文件的
<Directory>指令(如果有权限的话)
如果你能修改Apache的主配置文件或虚拟主机配置,可以用<Directory>指定目录,再配合<Files>:<Directory "/path/to/your/server/root/subdir/folder"> <Files "specific.php"> Require all granted </Files> </Directory>不过
.htaccess里不能用<Directory>指令,只能在主配置里用。
备注:内容来源于stack exchange,提问作者John Doe
相关产品推荐
相关产品推荐

