tp5.1升级至tp8.0后,config/database.php需彻底重构:移除顶层hostname等键,改用connections.default嵌套结构,必须设置deploy=>1、pooling=>true、params=>[],并强制使用db::connect()调用,否则连接复用率低于40%且查询静默失败。

TP5.1 升级到 TP8.0 后,config/database.php 不只是字段名微调,而是连接模型、池化机制、驱动契约全变了——直接复制旧配置会导致连接复用率低于 40%、查询静默失败、甚至 Db::connect() 返回 null。
database.php 结构与键名必须重写
TP8.0 的数据库配置不再兼容 TP5.1 的扁平结构,'type' => 'mysql' 这类顶层键已移除,所有驱动配置必须收进 'connections' 子数组,且每个连接需显式声明 'deploy' 和 'pooling'。
- 删掉 TP5 风格的
'hostname'、'database'、'username'等顶层键,它们在 TP8 中无效 - 把原配置整体挪进
'connections' => ['default' => [...]],并补全'deploy' => 1(启用读写分离识别)和'pooling' => true(开启连接池) -
'params'数组必须存在,哪怕为空:'params' => [];缺了它,PDO 构造时会因缺少默认选项而抛出PDO::__construct(): Argument #4错误
连接池启用后必须显式调用 Db::connect()
TP8.0 默认不复用单例连接,Db::name('user') 已被彻底移除,继续使用会返回空结果而非报错——这是最隐蔽的坑。
- 所有查询必须改用
Db::connect('default')->table('user')->where(...)->find() - 若项目用了多库(如日志库、统计库),需在
connections中定义多个键(如'log'、'stat'),并在代码中显式传入:Db::connect('log')->table('log_action') - 不调用
Db::connect()就直接Db::table(),TP8 会 fallback 到无池化的临时连接,千级并发下连接创建耗时占比飙升至 60%+
MySQL 服务端参数必须同步调优
TP8.0 的连接池依赖 MySQL 服务端配合,否则连接复用率上不去,wait_timeout 设置不当还会导致空闲连接被服务端主动断开,引发 MySQL server has gone away。
- 检查
/etc/mysql/my.cnf,确认以下三项存在且值合理:max_connections = 300、wait_timeout = 300、interactive_timeout = 300 -
wait_timeout必须 ≥ TP8 连接池的'lifetime'配置(默认 3600),否则连接池内连接会在 PHP 层还活跃时被 MySQL 强制关闭 - 执行
SHOW VARIABLES LIKE 'wait_timeout';验证生效,若仍显示 28800(8 小时),说明配置未加载,需重启 MySQL
Redis 缓存驱动不能和 DB 共用同一连接池
TP8.0 中 cache 和 database 是完全隔离的组件,config/cache.php 里的 'default' => 'redis' 和 config/database.php 里的 Redis 配置互不影响——但很多人误把 Redis 连接信息写进 database 配置,导致 Cache::get() 失败。
- Redis 作为缓存驱动,只应在
config/cache.php的'stores.redis'下配置 host/port/database -
config/database.php中的'type' => 'redis'是非法值,TP8 不支持 Redis 当数据库驱动;若真要操作 Redis 表,应通过think\facade\Cache或原生Redis::set() - DB 配置里出现
'redis'字样,基本可以确定是复制粘贴错误,删掉即可
最易被忽略的是:TP8.0 的连接池不会自动探测主从状态,'deploy' => 1 开关必须手动打开,否则即使配置了 'read'/'write' 数组,路由层也始终只打向 'default' 节点。











