应先查看PDOException的message字段获取真实错误:如“Connection refused”表示MySQL未启动或host/port不匹配,“Access denied”说明用户名密码或host不匹配,“No such file or directory”指向localhost与socket路径不一致;再检查配置项、.env加载条件及pdo_mysql扩展是否在CLI和Web环境均启用。

ThinkPHP 数据库配置出问题,八成不是代码写错了,而是框架压根没连上你认为它该连的库,或者连上了却把表名、字段名认成了另一套规则。报错往往藏在 PDOException 的 message 里,而不是 ThinkPHP 自己说的“连接失败”。
看懂 PDOException message 才算真正开始
ThinkPHP 不自己抛底层连接错误,真正报错的是 PDO 层。你看到的异常里如果含 PDOException,重点盯住它的 message:
- "SQLSTATE[HY000] [2002] Connection refused" → MySQL 服务根本没启动,或 host/port 对不上
- "SQLSTATE[HY000] [1045] Access denied for user" → 用户名、密码、host 三者中至少一个不匹配
- "SQLSTATE[HY000] [2002] No such file or directory" → 配置写了 localhost,但 MySQL 没监听 socket 文件(常见于 Mac M1 或 Docker)
别只盯着日志里“数据库连接失败”这句废话,直接翻 runtime/log/ 下最新日志,找到带 PDOException 的那一行,复制完整 message 再判断。
配置文件本身容易踩的坑
database.php 看似简单,但四个关键项必须同时满足:
立即学习“PHP免费学习笔记(深入)”;
- 'hostname'、'username'、'password'、'database' 四项已填且可被真实访问
- 'type' => 'mysql' 必须是小写、无空格、无下划线;禁止写成 'MySQL'、'mysqli'、'mysql '
- 'prefix' => 'tp_' 必须和数据库中所有表前缀完全一致,包括末尾下划线;写成 'tp' 或 'tp_ '(带空格)都会拼错表名
- 若启用 'deploy' => 1,会绕过 prefix 和 $name,强行按类名推导表名(如 User → user),导致查不到带前缀的表,应设为 0 或删掉
.env 配置没生效?三个硬性前提缺一不可
ThinkPHP 6+ 默认读 .env,但它不会自动加载——以下三点必须同时满足:
- .env 文件必须放在项目根目录(和 think 命令同级),不是 app/ 或 config/ 下
- APP_DEBUG 必须为 true,否则环境变量加载逻辑被跳过(最常被忽略)
- .env 里的键名必须全大写加下划线,如 DB_HOST=127.0.0.1,不能写成 db_host 或 Db_Host
验证是否加载成功,控制器里临时加一句:dump(env('DB_HOST'));。输出 null 就说明上面三点至少有一条没做到。
驱动缺失和环境错位是真·隐形杀手
报 "could not find driver",90% 是 PHP 根本没装或没启 pdo_mysql 扩展:
- 命令行运行 php -m | grep pdo,必须同时看到 pdo 和 pdo_mysql
- Web 环境下访问 phpinfo() 页面,搜索 PDO drivers,确认列表里有 mysql(小写、无前缀)
- CLI 和 Web 环境用的不是同一个 php.ini:终端执行 php --ini 查路径;Web 看 phpinfo() 页顶部 Loaded Configuration File;两个配置必须都启用 extension=pdo_mysql
Linux 下常见漏装:sudo apt install php-pdo php-mysql(Ubuntu/Debian);Windows 用户检查 php.ini 中是否去掉了 ;extension=php_pdo.dll 和 ;extension=php_pdo_mysql.dll 前的分号。



















