PHP连接MySQL报“Access denied”根本原因是MySQL用户认证失败,仅由用户名错误、密码错误或用户未被授权从当前host(如localhost与127.0.0.1视为不同)登录导致。

PHP 连接 MySQL 报 Access denied 的真实原因
这不是 PHP 本身权限问题,而是 MySQL 用户认证失败。常见于用 mysqli_connect() 或 PDO 初始化连接时抛出的错误,比如:Access denied for user 'root'@'localhost' (using password: YES)。根本原因只有三个:用户名错、密码错、或该用户没被授权从当前 host(如 localhost vs 127.0.0.1)登录。
检查 MySQL 用户权限和 host 匹配
MySQL 认证时会严格比对 user + host 组合。同一用户名在 'root'@'localhost' 和 'root'@'127.0.0.1' 是两个独立账户,权限可能不同。
- 登录 MySQL(用已有高权限账号)后执行:
SELECT User, Host FROM mysql.user;
- 确认你 PHP 中写的 host(如
'localhost')是否在结果中存在对应用户 - 若只看到
'root'@'127.0.0.1',但 PHP 用的是'localhost',就必然报错——此时要么改 PHP 的 host 为'127.0.0.1',要么给'root'@'localhost'授权 - 授权示例(在 MySQL 中执行):
CREATE USER 'myapp'@'localhost' IDENTIFIED BY 'strongpass';
GRANT ALL PRIVILEGES ON `mydb`.* TO 'myapp'@'localhost';
FLUSH PRIVILEGES;
PHP 创建数据库前必须确保连接用户有 CREATE 权限
即使能连上,也不代表能建库。CREATE DATABASE 需要显式授予的 CREATE 权限(或更高如 ALL PRIVILEGES),普通 SELECT/INSERT 权限不够。
- 检查权限:
SHOW GRANTS FOR 'myapp'@'localhost';
- 如果输出里没有
GRANT CREATE ON *.*或类似项,就缺权限 - 补授权(注意范围):
GRANT CREATE ON `mydb`.* TO 'myapp'@'localhost';
(仅允许建指定前缀的库)或GRANT CREATE ON *.* TO 'myapp'@'localhost';
(允许建任意库) - PHP 中创建数据库的典型写法:
$conn = new mysqli('localhost', 'myapp', 'strongpass');——注意这里不能带数据库名在连接参数里,否则会因库不存在而提前失败
$conn->query("CREATE DATABASE IF NOT EXISTS mydb CHARACTER SET utf8mb4");
本地开发常见陷阱:MySQL 8 默认认证插件变更
MySQL 8.0+ 默认用 caching_sha2_password 插件,而老版本 PHP(mysqli 驱动不兼容,会静默转成认证失败,表现就是 Access denied,哪怕账号密码完全正确。
立即学习“PHP免费学习笔记(深入)”;
- 临时验证方式:登录 MySQL 后运行
SELECT user, host, plugin FROM mysql.user WHERE user='myapp';
- 若
plugin是caching_sha2_password,且你无法升级 PHP,就降级认证插件:ALTER USER 'myapp'@'localhost' IDENTIFIED WITH mysql_native_password BY 'strongpass';
FLUSH PRIVILEGES; - 或者在 PHP 连接时强制指定 socket 或禁用 DNS 解析(避免 localhost 被解析成 IPv6 地址导致 host 不匹配)
真正卡住人的往往不是“没权限”,而是 MySQL 的 host 匹配规则、认证插件、权限粒度这三者叠加。每次报 Access denied,先查 mysql.user 表,再看 PHP 里写的 host 和密码是否和表中某一行完全一致——少一个字符、多一个空格、甚至大小写(部分系统下 host 区分大小写),都会失败。











