public目录必须是Web服务器根目录,因ThinkPHP6+入口统一为public/index.php,且document_root指向项目根目录会暴露敏感文件;Nginx配置中root须为绝对路径且无尾斜杠,并含try_files指令,Apache需开启AllowOverride All和mod_rewrite;runtime目录须位于项目根目录且赋予Web用户读写权限。

public目录必须是Web服务器的根目录
ThinkPHP 6+ 的设计强制要求 Web 服务器(Nginx/Apache)的 document_root 指向 public 目录,而不是项目根目录。这是由其入口文件 public/index.php 和自动加载机制决定的——所有请求必须经由该入口统一调度,否则 vendor/autoload.php 找不到、配置无法加载、路由解析失败,直接报 Class 'think\App' not found 或空白页。
- 如果 document_root 指向项目根目录(如
/var/www/myapp/),访问https://example.com/会暴露app/、config/、.env等敏感目录,存在严重安全风险 -
public/是唯一被设计为“可公开访问”的目录,它内部已通过.htaccess(Apache)或location规则(Nginx)屏蔽了对.env、runtime/等路径的直接访问 - 本地开发用
php think run不受影响,但该命令仅用于调试;生产环境必须走 Web 服务器真实部署
Nginx 配置中 document_root 必须写绝对路径且结尾不带斜杠
常见错误是写成 root /var/www/myapp/public/;(末尾斜杠),这会导致 Nginx 在拼接 fastcgi_script_name 时多出一层路径,最终 PHP 解析到 public/public/index.php 报 404;或者漏掉 try_files 导致静态资源(CSS/JS)返回 404。
- 正确写法:
root /var/www/myapp/public;(无尾部斜杠) - 必须包含
try_files $uri $uri/ /index.php?$query_string;,否则除首页外所有路由都 404 - 务必检查
fastcgi_param SCRIPT_FILENAME是否为$document_root$fastcgi_script_name,不能硬编码路径 - 若使用宝塔、cPanel 等面板,需在站点设置里手动修改“网站目录”为
/var/www/myapp/public,而非项目根目录
Apache 下启用 rewrite 后仍 404?检查 .htaccess 是否生效
ThinkPHP 的 public/.htaccess 是 Apache 路由重写的依据,但它不会自动生效——需要确认 AllowOverride All 已开启,且 mod_rewrite 已启用。否则所有请求都直接返回 404,连 index.php 都不执行。
- 检查 Apache 配置中对应虚拟主机的
块内是否有AllowOverride All - 运行
a2enmod rewrite并重启 Apache(Debian/Ubuntu);CentOS 用yum install mod_rewrite或检查/etc/httpd/conf.modules.d/00-base.conf - 若用 XAMPP/MAMP,.htaccess 默认可能被禁用,需在
httpd.conf中取消注释LoadModule rewrite_module modules/mod_rewrite.so并设AllowOverride All - Windows 下注意路径大小写:.htaccess 文件名必须全小写,不能是
Htaccess或.HTACCESS
部署后提示 “The runtime directory does not exist” 或 500 错误
这不是路径指向问题,而是权限或目录缺失。ThinkPHP 运行时依赖 runtime/ 目录(位于项目根目录下),而 Web 服务器用户(如 www-data 或 nginx)必须对该目录有读写权限——但这个目录**不在 public 下,也不应被 Web 访问**。
- 确保项目根目录下存在
runtime/,且权限为755或更宽松(如775),属主为 Web 用户:chown -R www-data:www-data /var/www/myapp/runtime - 不要把
runtime/放进public/,否则会被 Web 直接访问,造成安全隐患 - 如果用了容器部署(Docker),需在
Dockerfile或docker-compose.yml中提前创建并授权runtime/目录,不能只靠首次请求自动创建(可能因权限不足失败) - 某些共享主机禁用
opcache.restrict_api或禁用symlink(),也会导致 runtime 初始化失败,需联系服务商确认
最常被忽略的是 runtime 目录权限和 Nginx root 路径末尾斜杠——这两个点一错,整个站就挂得无声无息。别信“本地能跑线上就一定行”,Web 服务器配置和文件系统权限才是生产环境真正的门槛。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










