Composer 安装 ThinkPHP 8 需满足 PHP ≥ 8.1 并启用 curl、mbstring、json、openssl 扩展,使用带 --stability=stable 和 --remove-vcs 参数的 create-project 命令,Web 服务器必须指向 public/ 目录并正确配置路由引导文件 router.php。

Composer 安装 ThinkPHP 8 不是“一键安装”就能开干的事——它必须基于 PHP 环境、扩展和权限的正确组合,否则会卡在 composer create-project 报错或安装后 index.php 白屏。
PHP 版本和扩展没配对,create-project 直接失败
ThinkPHP 8 要求 PHP ≥ 8.1,且必须启用 curl、mbstring、json、openssl 这四个扩展。Windows 用户常漏掉 php.ini 中的 extension=openssl(默认被注释);Linux 用户用 apt install php-curl php-mbstring 后,还得确认 CLI 和 Web SAPI 用的是同一份配置(php -v 和 phpinfo() 对比 Loaded Configuration File)。
- 运行
php -m | grep -E "curl|mbstring|json|openssl"确认 CLI 下已加载 - 用
php -i | grep "Configuration File"查 CLI 配置路径,别只改了 Apache 的php.ini - 如果报
Could not parse version constraint ^8.0: Invalid version string "^8.0",说明 Composer 版本太老,升级到composer v2.5+:运行composer self-update
composer create-project 命令要加参数才干净
直接跑 composer create-project topthink/think 会拉最新稳定版(可能是 TP8.x),但默认不带 public 入口目录结构,也不初始化 Git,容易误删核心文件。推荐用带参数的写法:
composer create-project topthink/think tp8 --stability=stable --remove-vcs
-
--stability=stable防止意外拉到dev-main分支(不稳定、文档不同步) -
--remove-vcs清掉 vendor 里所有 .git,避免后续项目 git push 冲突 - 别用
-n(no-interaction)跳过交互,TP8 初始化时会生成.env并提示设置 APP_DEBUG,跳过会导致调试关闭、错误不显示
Web 服务器入口路径必须指向 public/,否则 404 或白屏
TP8 不再允许根目录直访 index.php,所有请求必须经由 public/index.php。Apache 默认 DocumentRoot 是项目根目录,Nginx 则常配错 root 指向。
立即学习“PHP免费学习笔记(深入)”;
- Apache:把
DocumentRoot改成/path/to/tp8/public,并确保.htaccess可读(AllowOverride All) - Nginx:
root必须设为/path/to/tp8/public,不是/path/to/tp8;重写规则里try_files $uri $uri/ /index.php?$query_string;才有效 - 本地开发用
php -S:进public/目录再执行php -S localhost:8000 router.php,别在项目根目录跑
.env 文件权限和内容影响调试与数据库连接
TP8 启动时优先读 .env,但若文件不可读(如 Linux 下权限为 600 且 Web 用户非文件所有者),就会静默 fallback 到默认配置——表现为数据库连不上、APP_DEBUG 关闭、路由不生效。
-
.env文件权限建议644,确保 Web 服务器用户(如www-data或_www)有读取权 - 修改
APP_DEBUG=true后,必须清空runtime/cache/和runtime/container/,否则旧缓存会屏蔽新配置 - 数据库配置写
DB_HOST=127.0.0.1,别用localhost(MySQL 会走 socket,TP8 PDO 默认不兼容)
最常被忽略的是:TP8 的 router.php 是单入口路由引导文件,它不在 index.php 里硬编码,而是由 Web 服务器显式调用。这意味着哪怕代码没错,只要服务器没按这个约定转发请求,就永远看不到 “Hello World”。











