入口文件 index.php 必须改 dir 路径,因其在子目录部署时指向 public 目录,导致 ../thinkphp/start.php 等相对路径失效;应改用绝对路径或定义 root_path 显式拼接 think_path 和 app_path。

入口文件 index.php 为什么必须改 __DIR__ 路径?
ThinkPHP 默认假设项目部署在 Web 根目录,index.php 里用 __DIR__ . '/../thinkphp/start.php' 这类路径会失效——子目录部署时,__DIR__ 指向的是子目录下的 public,往上两级可能根本找不到框架源码。
实操建议:
- 把
__DIR__替换为绝对路径或基于当前 URL 的动态定位,更稳妥的是显式声明THINK_PATH和APP_PATH - 在
index.php开头加一行:define('ROOT_PATH', dirname(dirname(__FILE__)) . '/');,再用它拼接路径 - 确保
APP_PATH指向的是application目录的**绝对物理路径**,不是相对 URL 路径 - 如果用 Composer 自动加载,检查
vendor/autoload.php的引入路径是否也受子目录影响(通常不会,但本地测试时容易误判)
Apache 的 .htaccess 重写规则为什么总 404?
子目录部署下,RewriteBase 缺失或写错是最常见原因。默认规则假设请求从根开始匹配,但实际 URL 是 /myapp/index.php/s/xxx,RewriteRule 却还在按 ^.*$ 匹配整个 URI,没剔除子目录前缀。
实操建议:
- 在子目录的
.htaccess中,第一行必须加:RewriteBase /myapp/(把myapp换成你的子目录名) - 确认 Apache 已启用
mod_rewrite,且AllowOverride All已配置到该目录的<directory></directory>块中 - 避免直接复制根目录的规则;子目录版应类似:
RewriteEngine On RewriteBase /myapp/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,PT,L] - 注意末尾斜杠:如果子目录 URL 不带尾部
/(如/myapp),RewriteBase也别加,否则重写会多出一个//
Nginx 子目录路由重写怎么写才不丢 _url 参数?
Nginx 没有 RewriteBase 概念,location 匹配后,try_files 或 rewrite 必须显式补全子目录路径,否则 $_SERVER['PATH_INFO'] 或 $_GET['_url'] 会漏掉前缀,导致路由解析失败。
当代理已经知道网站路由或内容URL,并且在启动前需要有效的sitemap XML、sitemap索引或robots.txt引用时,请使用sitemap。这是一个发布构件技能,而不是爬虫或SEO平台。
实操建议:
- 用
location ^~ /myapp/精确匹配子目录,内部用alias指向物理路径,别用root - 关键点:在
fastcgi_param SCRIPT_FILENAME后,手动设置PATH_INFO,例如:fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param SCRIPT_NAME /myapp/index.php;
- 推荐 rewrite 方式(更可控):
location /myapp/ { alias /var/www/html/myapp/public/; try_files $uri $uri/ /myapp/index.php?$query_string; } location ~ \.php$ { include fastcgi_params; fastcgi_pass php-fpm; fastcgi_param SCRIPT_FILENAME $request_filename; }注意$request_filename在 alias 下才是正确路径 - 务必验证
$_SERVER['SCRIPT_NAME']是否为/myapp/index.php,这是 ThinkPHP 解析路由前缀的依据
为什么开启 url_common 后子目录路由还是 404?
ThinkPHP 的 url_common(兼容模式)依赖 PATH_INFO,而子目录环境下,Web 服务器传入的 PATH_INFO 往往包含子目录前缀(如 /myapp/a/b),但框架默认只截取 /a/b 部分,若没配置好 url_domain_deploy 或 url_pathinfo_fetch,就会解析失败。
实操建议:
- 在
config/app.php中显式设置:'url_domain_deploy' => true,让框架自动剥离子目录前缀 - 检查
url_pathinfo_fetch是否为['PATH_INFO', 'REDIRECT_PATH_INFO'],Nginx 下常需加REDIRECT_PATH_INFO - 如果用 Apache,确保
AcceptPathInfo On已开启,否则PATH_INFO可能为空 - 调试时临时加一行:
dump($_SERVER['PATH_INFO'], $_SERVER['SCRIPT_NAME']);,看前缀是否被正确识别和剥离
子目录适配最易被忽略的,是 Web 服务器传给 PHP 的环境变量与 ThinkPHP 内部路由解析逻辑之间的“前缀对齐”。差一个斜杠、少一个 RewriteBase、漏一个 url_domain_deploy,都可能让路由表完全失效,而不是报错——它只是默默返回 404。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










