ThinkPHP 5.1 子目录部署伪静态需三者协同:Nginx 正确转发(如 location /myapp/ + try_files 截断路径)、框架识别前缀(定义 BASE_PATH、启用 url_domain_deploy)、路由生成自动适配(全用 url() 函数,避免硬编码)。

ThinkPHP 5.1 在子目录部署(如 https://example.com/myapp/)时,伪静态配置需同时满足三件事:Nginx 正确识别子目录路径、框架能解析带前缀的 URL、所有路由生成和跳转自动适配该路径。关键不在多写规则,而在路径对齐与参数完整传递。
一、Nginx 配置必须加子目录前缀
入口文件 index.php 实际位于 /myapp/public/index.php,所以 Nginx 的 try_files 必须指向该相对路径,且 s= 参数要保留原始 URI 去掉子目录后的部分:
- 在 server 块中定义 location 时,路径需显式匹配子目录:
location /myapp/ { - 使用
try_files转发,注意$uri是带/myapp/的完整请求路径,需用rewrite截断或用fastcgi_param修正:try_files $uri $uri/ /myapp/public/index.php?s=$1&$args; - 更稳妥的做法是配合正则捕获(推荐):
location ~ ^/myapp/(.*)$ {<br> try_files /myapp/public/$1 /myapp/public/index.php?s=/$1&$args;<br>} - 务必确认
root指向的是项目根目录(不是public),例如:root /var/www/html;(此时/myapp/public/就是完整物理路径)
二、框架层启用子目录感知
TP5.1 默认不自动识别部署子目录,需手动告知入口路径前缀:
- 在
public/index.php开头添加:define('BASE_PATH', '/myapp/'); - 修改
config/app.php中的 URL 配置:'url_domain_deploy' => true,'url_html_suffix' => '.html','pathinfo_depr' => '/', - 确保路由生成函数(如
url('index/index'))自动补上前缀 —— 这依赖于$_SERVER['SCRIPT_NAME']或$_SERVER['PHP_SELF']的准确性;若不生效,可在public/index.php中强制设置:$_SERVER['SCRIPT_NAME'] = '/myapp/public/index.php';
三、后台与前台路由仍可统一管理
子目录部署不影响前后台路由隔离逻辑,只需保证分组前缀与 URL 前缀叠加后语义清晰:
- 后台路由保持
->prefix('admin/'),最终访问地址为:https://example.com/myapp/admin/login - 前台文章页可定义为:
Route::rule('article/:id','index/article/read');
生成链接时用url('index/article/read',['id'=>123]),自动输出:/myapp/article/123 - 避免硬编码路径,所有模板中链接一律用
url()或Url::build()生成
四、常见失败点排查
子目录伪静态最容易卡在“404”或“白屏”,多数因以下任一环节断裂:
-
root 路径错误:Nginx 的
root指向了public/目录,导致/myapp/public/index.php实际变成/myapp/public/public/index.php -
SCRIPT_FILENAME 拼错:PHP 处理块中用了
$document_root但未同步更新到子目录层级,应改用$realpath_root并确认其值正确 -
GET 参数丢失:伪静态规则漏了
&$args,导致分页、搜索等带 query 的 URL 无法传递参数 -
HTTPS 下协议误判:若通过 CDN 或反向代理访问,需在
config/app.php显式设'url_secure' => true,并检查HTTP_X_FORWARDED_PROTO是否透传
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











