thinkphp 5.1 的 application 目录必须通过 nginx 的 location ~ ^/application/ { deny all; } 规则全路径前缀拦截,禁止任何后缀访问,防止 config/database.php 等敏感文件泄露;root 必须指向 public 目录,且子目录部署需同步调整 location 前缀。

location 正则匹配 application 目录直接拒绝
ThinkPHP 5.1 的 application 目录包含控制器、模型等核心源码,绝不能被 Web 直接访问。Nginx 不会自动继承 Apache 的 .htaccess 权限控制,必须显式配置拦截规则。
最稳妥的方式是用 location ~ ^/application/ 做前缀正则匹配,并立即返回 403:
location ~ ^/application/ {
deny all;
}
这条规则放在 server 块内任意位置都生效,但建议紧挨着其他敏感路径规则(如 config、data)便于维护。
-
~ ^/application/中的^确保只匹配以/application/开头的请求,不会误杀/myapplication这类路径 - 不要写成
location = /application—— 这是精确匹配,防不住/application/(带斜杠)或/application/route.php - 不要依赖
return 403,deny all在所有 Nginx 版本中语义更稳定,且不受allow/deny继承链干扰
为什么不能只拦 .php 文件而要拦整个目录
仅禁止 .php 后缀(如 location ~ \.php$)无法覆盖全部风险:
-
application/config.php可能被当成静态文件直接输出(尤其当 PHP-FPM 没接管该 location 时) -
application/database.php或application/.env.example会被原样下载,泄露数据库凭证 - 某些 Nginx 配置下,
index.html、README.md等非 PHP 文件也可能暴露目录结构
所以必须从路径维度封锁整个 /application/ URI 前缀,不区分后缀、不依赖 MIME 类型判断。
root 指向错误会导致 application 规则失效
如果 root 错误地设为项目根目录(如 /var/www/myapp),那么 location ~ ^/application/ 实际匹配的是 http://domain.com/application/ —— 但这个 URL 对应的物理路径是 /var/www/myapp/application/,而 Nginx 默认允许读取该路径下的文件,除非你明确 deny all。
更危险的是:若 root 指向了 public 目录(正确做法),那 /application/ 根本就不存在于该 root 下,此时规则虽不触发,但已天然隔离——这是双重保险。
- 务必确认
root是/var/www/myapp/public,不是/var/www/myapp - 用
curl -I http://localhost/application/测试,返回必须是403 Forbidden,而非404 Not Found或200 OK - 若返回 404,说明规则没生效;若返回 200,说明
root错了或规则位置被覆盖
别漏掉子目录部署时的路径前缀
如果你把 ThinkPHP 部署在子目录(如 https://example.com/myapp/),那么用户访问的是 /myapp/application/,而不是 /application/。
此时原规则 location ~ ^/application/ 完全不匹配,必须改成:
location ~ ^/myapp/application/ {
deny all;
}
或者更通用的写法(适配任意子目录):
location ~ ^/(?:[^/]+/)?application/ {
deny all;
}
但后者正则稍重,推荐在子目录场景下直接写死前缀,避免歧义和调试成本。
子目录部署时,application 的拦截只是冰山一角;PATH_INFO 解析、try_files 路径截断、SCRIPT_FILENAME 构造都得同步调整,否则看似拦住了目录,实际路由仍可能把请求错误转发进去。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











