Access denied 错误主因是权限、认证方式、主机白名单三者之一不匹配:检查用户名密码是否完全一致(含大小写及特殊字符);确认用户是否被授权从PHP所在主机(localhost/127.0.0.1/%/IP)连接;MySQL 8.0+需适配caching_sha2_password认证插件。

MySQLi 连接报 Access denied for user 怎么快速定位原因
这不是密码输错了就重试的问题,而是权限、认证方式、主机白名单三者之一卡住了。PHP 用 mysqli_connect() 或 PDO 连 MySQL 时出现这个错误,优先检查这三项:
-
用户名和密码是否与 MySQL 中实际创建的完全一致(注意大小写、特殊字符是否被 URL 编码或 shell 截断) - 该用户是否允许从 PHP 所在机器(
'localhost'、'127.0.0.1'、'%'或具体 IP)连接——localhost在 MySQL 里默认走 Unix socket,而127.0.0.1才走 TCP,二者权限记录是分开的 - MySQL 8.0+ 默认用
caching_sha2_password插件认证,但旧版 PHP(mysqlnd 的环境不支持,会直接拒连,不是密码错,是协议不认
PHP 7.4+ 连 MySQL 8.0 报 Access denied?先看认证插件
运行这条 SQL 查用户用的什么认证方式:
SELECT user, host, plugin FROM mysql.user WHERE user = 'your_user';
如果返回 caching_sha2_password,而你的 PHP 不支持(比如没编译 mysqlnd 或版本太低),就得换插件或升级驱动。临时解决方法(开发环境可用):
- 登录 MySQL 后执行:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_pass'; - 再执行
FLUSH PRIVILEGES; - 确保 PHP 使用的是
mysqli或PDO+mysqlnd驱动(phpinfo()查 “mysqlnd” 是否启用)
用 mysqli_connect() 连接时传参顺序和错误捕获别漏掉
常见写法错误:把端口混进主机名、没检查返回值、忽略错误信息。正确示范:
立即学习“PHP免费学习笔记(深入)”;
$conn = mysqli_connect('127.0.0.1', 'myuser', 'mypass', 'mydb', 3306);
if (!$conn) {
die('Connect Error: ' . mysqli_connect_error()); // 必须加这句,否则只看到空白页
}注意:localhost → Unix socket;127.0.0.1 → TCP;端口必须显式传第 5 个参数,不能写成 'localhost:3306'(mysqli 不识别这种格式)
Docker 或远程服务器连不上?重点查 host 权限和防火墙
本地 PHP 脚本连宿主机 MySQL,或容器内 PHP 连外部 DB,常因 MySQL 绑定地址或防火墙拦截失败:
- 确认 MySQL 配置中
bind-address是0.0.0.0(非仅127.0.0.1) - 用户授权语句必须含具体来源,例如:
GRANT ALL ON mydb.* TO 'myuser'@'172.17.0.1' IDENTIFIED BY 'mypass';(Docker 默认网段) - Linux 上检查
ufw status或iptables -L,云服务器还要过安全组(阿里云/腾讯云控制台里开 3306 入方向)
这类问题的表现是:命令行 mysql -h 127.0.0.1 -u xxx -p 能连,但 PHP 死活报 Access denied——大概率是用户权限没给对 host,而不是账号密码本身有问题。











