MySQL错误1045根本原因是凭据不匹配,需确认用户存在、host精确一致(localhost≠127.0.0.1)、认证插件兼容(推荐mysql_native_password)、PHP实际加载的凭证正确,并通过命令行验证连接目标实例。

MySQL 错误 1045 表示连接被拒绝,根本原因是 PHP 尝试用错误的用户名或密码连接数据库,不是代码语法问题,也不是服务没启动,而是凭据不匹配。
确认 MySQL 用户是否存在且允许从当前主机连接
PHP 连接时用的 host(比如 'localhost'、'127.0.0.1' 或远程 IP)必须和 MySQL 中创建用户时指定的 host 完全一致。MySQL 把 'localhost' 和 '127.0.0.1' 视为两个不同主机:
-
'localhost'走 Unix socket,不走 TCP/IP -
'127.0.0.1'强制走 TCP/IP,需对应'user'@'127.0.0.1'权限
执行以下命令检查:
mysql -u root -p -e "SELECT User, Host FROM mysql.user;"
若看到 myapp@'localhost',但 PHP 里写的是 host => '127.0.0.1',就会报 1045。
立即学习“PHP免费学习笔记(深入)”;
重置密码并刷新权限(MySQL 8+ 和旧版操作不同)
MySQL 8+ 默认使用 caching_sha2_password 插件,老版本 PHP 扩展(如 mysqlnd 低版本)可能不兼容,导致“密码正确也报 1045”。建议统一用 mysql_native_password:
ALTER USER 'your_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_new_password';
FLUSH PRIVILEGES;
如果不确定插件类型,先查:
SELECT user, host, plugin FROM mysql.user WHERE user = 'your_user';
常见操作组合:
- 改密码 + 换认证插件:
ALTER USER 'test'@'%' IDENTIFIED WITH mysql_native_password BY '123456'; - 授权所有库:
GRANT ALL PRIVILEGES ON *.* TO 'test'@'%'; - 别漏掉:
FLUSH PRIVILEGES;
检查 PHP 连接代码里的凭证是否硬编码或被覆盖
容易被忽略的点:凭证可能来自配置文件、环境变量或框架封装,实际运行时加载的不是你以为的那个值。
- 打印调试:
echo "Host: {$host}, User: {$user}, Pass: {$pass}";(注意不要上线) - 确认
.env文件没被.env.local覆盖(Laravel 等框架) - 检查
php.ini是否启用了variables_order = "EGPCS",否则$_ENV可能为空 - CLI 运行和 Web 运行用的可能是两套环境变量(比如 Apache 的
SetEnv和 shell 的export不同步)
测试连接是否真的通——绕过 PHP 直接验证
在服务器上用命令行模拟 PHP 的连接方式,最能定位是“账号问题”还是“网络/防火墙问题”:
- 连本地 socket:
mysql -u your_user -p your_database - 连 TCP:
mysql -h 127.0.0.1 -P 3306 -u your_user -p your_database - 连远程:
mysql -h 192.168.1.100 -u your_user -p your_database
如果命令行也报 Access denied for user 'xxx'@'yyy',说明问题 100% 出在 MySQL 用户权限或密码;如果命令行成功但 PHP 失败,重点查 PHP 配置、字符集(如 utf8mb4 影响认证)、或 SELinux/AppArmor 限制。
真正卡住的地方,往往不是“密码输错了”,而是“你连的不是你以为的那个 MySQL 实例”,比如 Docker 容器里跑了一个、宿主机又装了一个,PHP 连的是空密码的本地实例,而你改的是容器里的用户。











