直接结论:报错本质是MySQL 8.0默认caching_sha2_password认证插件与PHP≤7.3或集成环境不兼容,需执行ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password BY 'pwd'并FLUSH PRIVILEGES,且ThinkPHP中hostname须设为127.0.0.1而非localhost。

直接结论:这不是 ThinkPHP 配置写错了,而是 MySQL 8.0 默认用 caching_sha2_password 认证,而你当前 PHP 环境(尤其是 PHP ≤ 7.3 或未更新扩展)压根不认它——连接在握手阶段就断了。
确认是不是认证插件导致的
别猜,进 MySQL 命令行执行这句,看实际生效的插件:
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';
重点看 plugin 列。如果是 caching_sha2_password,且你用的是 PHP 7.2/7.3 或 phpEnv、XAMPP 等集成环境,默认就是它拦路。注意:'root'@'localhost' 和 'root'@'%' 是两个独立用户,得分别查、分别改。
ALTER USER 改认证方式(最稳、不用重启 MySQL)
对目标用户执行一条 SQL 即可,兼容所有托管云数据库(如阿里云 RDS):
立即学习“PHP免费学习笔记(深入)”;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';- 执行
FLUSH PRIVILEGES;
⚠️ 如果报 ERROR 1396 (HY000),说明该 user@host 组合根本不存在,先用 CREATE USER 补上再改。
ThinkPHP 配置里必须写 127.0.0.1,别写 localhost
Windows 下 localhost 可能走命名管道或 IPv6 回环,触发超时或二次报错 SQLSTATE[HY000] [2054]。在 config/database.php 中确保这几项明确:
-
'hostname' => '127.0.0.1'(不是localhost) -
'hostport' => 3306(显式写数字,别留空或字符串) -
'username' => 'root'(对应你刚改过插件的那个用户) -
'password' => 'your_password'(密码要和ALTER USER里一致) -
'database' => 'test_db'(库名必须已存在,否则会报Unknown database) -
'db_type' => 'mysql'(别漏,TP8 不自动推导)
先绕开框架,用原生 mysqli 验证通不通
写个最小验证脚本 test_db.php,浏览器直访:
<?php
$mysqli = new mysqli('127.0.0.1', 'root', 'your_password', 'test_db', 3306);
if ($mysqli->connect_error) {
die('Connect Error: ' . $mysqli->connect_error);
}
echo 'OK, MySQL is reachable';
$mysqli->close();
?>
只有这里输出 OK, MySQL is reachable,才能进下一步。否则错误信息(比如 Connection refused、Access denied)才是真实瓶颈,框架层的日志只会干扰判断。
真正容易被忽略的是:云数据库只允许用户级修复,my.cnf 全局改 default_authentication_plugin 在 RDS/CDB 上根本不可行;还有,ALTER USER 必须严格匹配 user@host,少一个 % 或多一个空格都会失败。



















