ThinkPHP子目录部署隐藏index.php的关键是Nginx或Apache精准识别项目路径并转发请求至public/index.php:Nginx需设root指向public目录、location匹配带前缀路径(如/myapp/)、try_files回退至/myapp/index.php?s=$uri&$args,并配置fastcgi_split_path_info提取PATH_INFO;Apache需在.htaccess中声明RewriteBase /myapp/,且DocumentRoot指向public目录,同时ThinkPHP需配置app_host或url_domain_deploy以适配子目录URL生成。

ThinkPHP子目录部署时隐藏index.php,关键在于让Nginx或Apache正确识别项目实际路径,并将所有非静态请求精准转发到子目录下的public/index.php,同时保留PATH_INFO或QUERY_STRING的完整性。直接套用根目录配置会失败,必须显式声明部署前缀。
确认部署结构与root指向
假设项目部署在/var/www/html/myapp/,完整路径为/var/www/html/myapp/public/,那么Nginx的root必须指向public目录本身,而不是上层:
-
正确:
root /var/www/html/myapp/public; -
错误:
root /var/www/html/myapp;(会导致/index.php找不到)
Apache同理:虚拟主机的DocumentRoot应设为/var/www/html/myapp/public,而非项目根目录。
Nginx子目录专用配置(推荐try_files + s参数)
若访问地址是https://example.com/myapp/xxx,需在location /myapp/块中配置,且所有重写路径带前缀:
立即学习“PHP免费学习笔记(深入)”;
- 主location匹配带前缀的请求:
location /myapp/ { try_files $uri $uri/ /myapp/index.php?s=$uri&$args; } - PHP处理块需匹配
.php并兼容子路径:location ~ ^/myapp/.+\.php($|/) { -
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;(确保$document_root指向public) - 务必添加
fastcgi_split_path_info ^(.+\.php)(/.*)$;和fastcgi_param PATH_INFO $fastcgi_path_info;,否则路由无法解析/myapp/user/profile中的模块信息
Apache子目录适配要点(RewriteBase不可省)
在public/.htaccess中,必须声明RewriteBase,否则重写规则默认按网站根目录计算,导致404:
-
RewriteBase /myapp/(末尾斜杠不能少) - 完整规则示例:
<IfModule mod_rewrite.c><br>RewriteEngine On<br>RewriteBase /myapp/<br>RewriteCond %{REQUEST_FILENAME} !-f<br>RewriteCond %{REQUEST_FILENAME} !-d<br>RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]<br></IfModule> - 确认虚拟主机中已启用
AllowOverride All,且mod_rewrite已加载
ThinkPHP端同步调整
框架需感知子目录路径,否则生成的URL仍含/myapp/index.php:
- 在
config/app.php中设置:'app_host' => 'https://example.com/myapp', - 或使用相对路径配置:
'url_domain_deploy' => true,并确保url_html_suffix等不影响路由 - TP6+建议开启
'url_pathinfo_convert' => true,配合Nginx的PATH_INFO传递 - 清除浏览器缓存及框架
runtime/cache,避免旧301跳转干扰验证



















