90%的数据库连接失败源于host配置错误或环境不匹配:localhost默认走unix socket而thinkphp走tcp,应统一用127.0.0.1;docker中须用容器名或host.docker.internal;mac m1需确认mysql启用bind-address=127.0.0.1且skip-networking=off;port必须为整数;.env需在根目录、app_debug=true、键名全大写下划线;mysql 8.0+需改认证插件为mysql_native_password;cli与web的php.ini可能不同,需分别检查pdo_mysql扩展。

连不上不是配置写错了,就是环境没对上——90% 的 case 都卡在这两点。直接看下面几个高频出问题的地方。
host 和 localhost 到底能不能混用
不能。localhost 在 MySQL 客户端里默认走 Unix socket,而 ThinkPHP 默认走 TCP;哪怕你 host 写成 'localhost'、port 写成 3306,PDO 也可能静默降级为 socket 连接,结果报 No such file or directory。
- 统一用
'127.0.0.1',别写'localhost' - Docker 环境下必须写容器名(如
'mysql')或'host.docker.internal',127.0.0.1指向容器自己 - Mac M1 + Homebrew 装的 MySQL,默认只监听 socket 文件,得确认
mysqld启用了bind-address = 127.0.0.1且skip-networking = OFF
port 是字符串还是整数
必须是整数。ThinkPHP 5.1+ 把 hostport(TP6)或 DB_PORT(TP5)传给 PDO 构造函数时,类型不对会触发警告,然后自动 fallback 到默认端口(3306),但如果你的 MySQL 实际监听的是 3307,就彻底连不上。
- 写成
'3306'(字符串)→ 错 - 写成
3306(整数)→ 对 - TP6 的
database.php里字段名是'hostport',不是'port';TP5 是'DB_PORT'
.env 文件不生效的三个硬条件
ThinkPHP 6+ 默认读 .env,但它不是“放那儿就管用”。漏掉任意一个,env('DB_HOST') 就返回 null,配置全失效。
-
.env必须在项目根目录(和think可执行文件同级),不是config/或app/下 -
APP_DEBUG必须为true,否则环境变量加载逻辑被跳过 - 键名必须全大写 + 下划线,比如
DB_HOST=127.0.0.1,写成db_host或DbHost都无效
验证方式:控制器里加一行 dump(env('DB_HOST'));,输出 null 就说明没加载成功。
MySQL 8.0+ 认证插件不兼容
错误信息里带 caching_sha2_password,基本就是这个原因。PHP 7.4 以下、部分 PDO 扩展版本不支持 MySQL 8.0 默认认证方式,连都连不进,更别说查数据。
- 不要降级 MySQL,改用户认证方式即可:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; - 如果是本地开发,建用户时就指定:
CREATE USER 'dev'@'%' IDENTIFIED WITH mysql_native_password BY '123'; - TP6 中如果手动写了
'dsn'字段,它会忽略所有其他连接参数,此时必须确保 DSN 字符串里也显式声明了;charset=utf8mb4,否则可能因字符集不匹配再报错
真正容易被忽略的是:CLI 和 Web 环境的 php.ini 往往不同,pdo_mysql 扩展在一个环境开了,另一个可能根本没启——连 php -m | grep pdo 都不能代表网页能连上。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











