默认执行 composer create-project topthink/think 安装的是 TP8,需 PHP ≥ 8.1;装 TP6 必须显式指定版本如 "6.*" 或 "6.3.10",且入口必须指向 public/ 目录,调试需开启 APP_DEBUG 并确保 runtime 可写。

直接执行 composer create-project topthink/think 会装 TP8,不是 TP6
这是当前(2026 年初)最常被忽略的前提:不加版本约束时,composer create-project topthink/think 默认拉取的是 topthink/think 包的最新稳定版 —— 即 TP8.x。如果你的 PHP 是 7.4 或 8.0,这条命令会卡在依赖解析阶段,报错类似:Conclusion: don't install topthink/framework v8.0.0 或更直白的 ParseError: syntax error, unexpected token "string"。
- 要装 TP8(推荐新项目),PHP 必须 ≥ 8.1,且已启用
curl、mbstring、openssl、json - 要装 TP6(如维护旧系统或兼容低版本 PHP),必须显式指定版本范围,例如:
composer create-project topthink/think tp6 "6.*"或锁定 LTS 版本:composer create-project topthink/think tp6 "6.3.10" - 别用
composer require topthink/framework往空目录硬塞 —— 那只会下载核心库,没有public/index.php、没有app/目录结构,也跑不起来
安装后访问 404 或空白页?大概率是入口路径或调试开关没调对
TP6 和 TP8 都强制要求 Web 服务器 root 指向 public/ 目录,而不是项目根目录。直接双击打开 public/index.php 或用浏览器访问 file://... 路径,必然报 Undefined index: SERVER_NAME;而用 php -S 启动又没配路由器文件,所有请求都会 404。
- 快速验证:进项目根目录,运行
php think run(TP8)或php think serve(TP6),访问http://127.0.0.1:8000 - 检查
.env文件中APP_DEBUG = true是否开启 —— 关闭状态下错误全被吞掉,只剩空白页 - 确认
runtime/目录可写(Linux/macOS 下常见问题:chmod -R 755 runtime)
php think run 和 php think serve 不是同一套命令
TP8 新增了 php think run 命令,底层封装了更健壮的内置服务器逻辑,支持自动重载和默认路由 fallback;而 TP6 仍使用 php think serve,本质是调用 PHP 自带的 php -S,需手动传参或依赖 server.php 路由器文件。
- TP8 中运行
php think serve会报错:Command "serve" is not defined - TP6 中运行
php think run会提示:Command "run" is not defined - 两者都不支持在非项目根目录下执行 —— 报
Class 'think\Console' not found就说明你没cd进去,或者vendor/autoload.php根本没加载
多应用、自动加载、URL 重写 —— 这些不是“装完就完”的事
Composer 安装只解决骨架和依赖,但 ThinkPHP 的运行逻辑深度绑定在几处关键配置上:多应用模式需要手动执行 php think build admin 才生成 app/admin/ 目录;app/ 下的类能被自动加载,靠的是 composer.json 里预设的 PSR-4 映射;而 URL 路由能正常工作,完全依赖 Apache 的 .htaccess 或 Nginx 的 rewrite 规则指向 /index.php?s=。
立即学习“PHP免费学习笔记(深入)”;
- 没运行
php think build就直接访问/admin,必然 404 —— 因为app/admin根本不存在 - 改了控制器命名空间(比如写成
app\controller\admin\Index),但 TP6 多应用要求是app\admin\controller\Index,自动加载器就找不到类 - Nginx 配置漏了
location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?s=$1 last; } },所有带参数的 URL 全挂
真正卡住人的从来不是“怎么装”,而是这些环境与框架契约之间的隐性约定 —— 它们不会报错,只会静默失败。











