MySQL错误1045根本原因是凭据不匹配,需确认用户存在、host精确一致(localhost≠127.0.0.1)、认证插件兼容(推荐mysql_native_password)、PHP实际加载的凭证正确,并通过命令行验证连接目标实例。
MySQL 错误 1045 表示连接被拒绝,根本原因是 PHP 尝试用错误的用户名或密码连接数据库,不是代码语法问题,也不是服务没启动,而是凭据不匹配。
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+ 默认使用 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;
容易被忽略的点:凭证可能来自配置文件、环境变量或框架封装,实际运行时加载的不是你以为的那个值。
echo "Host: {$host}, User: {$user}, Pass: {$pass}";(注意不要上线).env 文件没被 .env.local 覆盖(Laravel 等框架)php.ini 是否启用了 variables_order = "EGPCS",否则 $_ENV 可能为空SetEnv 和 shell 的 export 不同步)在服务器上用命令行模拟 PHP 的连接方式,最能定位是“账号问题”还是“网络/防火墙问题”:
mysql -u your_user -p your_database
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_d
atabase
如果命令行也报 Access denied for user 'xxx'@'yyy',说明问题 100% 出在 MySQL 用户权限或密码;如果命令行成功但 PHP 失败,重点查 PHP 配置、字符集(如 utf8mb4 影响认证)、或 SELinux/AppArmor 限制。
真正卡住的地方,往往不是“密码输错了”,而是“你连的不是你以为的那个 MySQL 实例”,比如 Docker 容器里跑了一个、宿主机又装了一个,PHP 连的是空密码的本地实例,而你改的是容器里的用户。