
当使用.htaccess隐藏php文件扩展名时,若存在与php文件同名的目录(如video.php与/video/目录共存),apache会因mod_dir模块的directoryslash功能自动重定向到带斜杠的url,引发404错误。本文详解原因、复现逻辑及可靠解决方案。
在Apache环境中,.htaccess中常见的隐藏PHP扩展规则如下:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]该规则本意是:当请求的路径不对应真实存在的文件时,尝试在路径后自动追加 .php 后缀并重写(例如访问 /video → 内部映射为 /video.php)。看似简洁,却隐含一个关键前提:请求路径不能同时匹配一个真实目录。
问题根源在于 Apache 的 mod_dir 模块及其默认启用的 DirectorySlash On 行为。当用户请求 /video 时,Apache 会按以下顺序检查:
- 是否存在名为 video 的真实文件?→ 否(假设只有 video.php);
- 是否存在名为 video 的真实目录?→ 是(若存在 ./video/ 目录);
- 此时 mod_dir 会强制执行“目录安全重定向”,将请求 301 重定向至 /video/(带尾部斜杠),以防止目录遍历风险;
- 浏览器跳转后请求 /video/,而你的重写规则未覆盖该路径(^([^\.]+)$ 不匹配含斜杠的URI),最终返回 404。
这就是为何仅 video.php 出现异常——只要存在同名目录(哪怕为空),该冲突即触发;而 videos.php、videoo.php 等无对应目录,故正常工作。
立即学习“PHP免费学习笔记(深入)”;
✅ 可靠解决方案:
方案一(推荐):删除或重命名冲突目录
最直接有效的方式是确保没有与PHP文件同名的目录。例如,将 ./video/ 目录重命名为 ./video-resources/ 或 ./videos-dir/,彻底消除歧义。
方案二:禁用 DirectorySlash(仅限可信环境)
若必须保留同名目录且确认无安全风险,可在 .htaccess 中关闭自动斜杠重定向:
DirectorySlash Off
RewriteEngine On
# 先排除目录,再匹配文件
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]⚠️ 注意:DirectorySlash Off 可能带来目录列表暴露风险(当 Options Indexes 启用时),生产环境慎用。
方案三(增强健壮性):显式排除已知PHP文件同名路径
在重写前增加判断,优先处理明确的PHP文件路由:
RewriteEngine On
# 显式禁止将 video/ 视为目录处理(若 video.php 存在)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^video$ video.php [L]
# 通用规则(对其他页面)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)$ $1.php [L]? 总结建议:
- 始终检查服务器上是否存在与目标PHP文件同名的目录(大小写敏感,Linux下尤其注意);
- 优先采用「命名隔离」策略(如文件用 video-page.php,目录用 video-assets/),从源头避免冲突;
- 避免依赖 DirectorySlash Off,除非你完全掌控服务器安全配置;
- 调试时可通过 curl -I http://yoursite.com/video 查看是否返回 301 Moved Permanently 及 Location: /video/,快速定位是否为 mod_dir 干预所致。











