目录索引被禁止是Web服务器(Apache/Nginx)的安全默认行为,非PHP问题;Apache需配置Options +Indexes并确保AllowOverride All,Nginx需在location块设autoindex on等参数,但生产环境应禁用以防范敏感目录泄露。

目录索引被禁止,不是PHP的问题,而是Web服务器(Apache/Nginx)默认关闭了 Indexes 选项 —— 这其实是安全加固的正常表现,不是故障。
Apache 中如何开启目录索引(显示文件列表)
只有明确需要暴露目录结构时才开启,比如内部文档站、静态资源预览页。默认应保持关闭。
- 在虚拟主机配置或
.htaccess中添加:Options +Indexes - 确保父目录没用
Options -Indexes覆盖该设置 - 若用
.htaccess,必须确认对应<directory></directory>块中已设AllowOverride All,否则规则不生效 - 重启 Apache:
sudo systemctl restart apache2(Debian/Ubuntu)或sudo systemctl restart httpd(CentOS/RHEL)
Nginx 中没有 “Indexes” 概念,但可模拟目录列表
Nginx 本身不提供原生目录索引功能,需借助第三方模块(如 ngx_http_autoindex_module),且仅限静态路径,不适用于 ThinkPHP 等框架的动态路由场景。
- 启用需在
location块中显式打开:autoindex on; - 必须配合
autoindex_exact_size off;和autoindex_format html;才能生成可读页面 - 绝对不要在
/或/public根路径下开启 —— 会暴露runtime/、config/等敏感子目录(即使它们本身被 location 规则拦截,autoindex 仍可能绕过) - 常见错误:把
autoindex on;写在location ~ \.php$块里,这毫无意义,PHP location 不处理目录请求
为什么 ThinkPHP 项目里绝不能开目录索引
ThinkPHP 的敏感目录(application、config、runtime、common、extend)与入口目录 public 是平级关系。一旦根目录开启索引,攻击者访问 http://domain.com/config/ 就可能直接看到 database.php 文件内容。
立即学习“PHP免费学习笔记(深入)”;
- Apache 下若漏配
<directory> Require all denied </directory>,+Indexes 会让整个目录可列、可下载 - Nginx 下若用正则匹配(如
location ~ ^/config/)而非location ^~ /config/,可能被通用try_files规则劫持,导致防御失效 - 本地开发用
php -S启动时,默认就带目录索引 —— 这是最大陷阱:它根本不管你的.htaccess或 Nginx 配置,纯属开发误用
真正该做的是禁止索引,而不是开启它
生产环境所有非 public/ 目录都应默认禁索引;public/ 下也只留 index.php 为唯一入口。所谓“开启索引”的需求,99% 是因调试时想快速确认文件是否存在 —— 正确做法是用 ls 或 SFTP 查看,而不是把风险暴露给 HTTP。
最容易被忽略的一点:public/ 目录下的子目录(如 public/upload/)如果允许用户上传,必须单独禁止 PHP 执行(Apache 用 <filesmatch> Require all denied </filesmatch>,Nginx 用 location ~ ^/upload/.*\.php$ { return 404; }),否则索引+上传=一键 GetShell。



















