SQLSTATEHY000 Access denied 错误根源在MySQL认证层:用户名、密码错误,或用户未被授权从当前host(如localhost/127.0.0.1)连接;localhost走Unix socket仅匹配'@localhost'权限,127.0.0.1走TCP匹配'@127.0.0.1'或'@%',需统一host配置并核查mysql.user表中user、host、plugin三字段。

直接说结论:SQLSTATE[HY000] [1045] Access denied 错误不是 ThinkPHP 的锅,是 MySQL 明确拒绝了你的登录请求——要么账号密码错,要么该用户没被授权从你当前的 host 连入。
为什么用 127.0.0.1 能连上,localhost 就报 Access denied?
因为 localhost 在 MySQL 里有特殊含义:它强制走 Unix socket,且只匹配 'user'@'localhost' 这条权限记录;而 127.0.0.1 是 TCP 连接,匹配的是 'user'@'127.0.0.1' 或 'user'@'%'。
- ThinkPHP 配置里写
'hostname' => 'localhost',但你数据库里只建了CREATE USER 'root'@'%' IDENTIFIED BY 'xxx';→ 必然失败 - Mac 上用 Homebrew 装的 MySQL,默认不监听 TCP,
localhost走 socket,127.0.0.1直接被拒 - 解决办法很实在:统一把配置改成
'hostname' => '127.0.0.1',再确认 MySQL 用户权限是否覆盖该 host
MySQL 用户权限查什么、怎么查?
别只看用户名密码对不对,重点查 host 字段和认证插件。执行以下 SQL:
SELECT user, host, plugin FROM mysql.user WHERE user = 'your_user';
- 如果
host是localhost,而 PHP 运行在 Docker 容器里(host 是容器 IP),那肯定被拒 - 如果
plugin是caching_sha2_password(MySQL 8.0+ 默认),而 PHP 版本 pdo_mysql 没编译--with-mysqlnd,也会表现为 Access denied - 临时修复命令:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_pass';
.env 文件里 DB_HOST 写对了,为啥还是连不上?
环境变量加载有硬性前提,漏一个就失效:
将 WCAG 2 AA 无障碍标准应用于设计系统、UI 组件和网页——通过可运行的验证器进行对比度计算,采用设计 token 模式使颜色天生可访问,设定排版和焦点状态规则,并提供语义检查清单。适用于构建或审查 UI。
立即学习“PHP免费学习笔记(深入)”;
-
.env文件必须放在项目根目录(和think命令同级),不是config/下 -
APP_DEBUG必须为true,否则 ThinkPHP 会跳过.env加载逻辑 - 键名必须全大写加下划线:
DB_HOST=127.0.0.1有效,db_host或Db_Host都读不到 - 验证是否生效:控制器里加一行
dump(env('DB_HOST'));,输出null就说明上面至少有一条没满足
Docker 环境下远程访问 MySQL 总被拒?
容器内连宿主机 MySQL,或外部连容器 MySQL,两个方向都容易卡在权限上:
- 容器内连宿主机:host 不能写
127.0.0.1(那是容器自己),得用host.docker.internal(Mac/Win)或宿主机真实局域网 IP(Linux) - 外部连容器 MySQL:除了
bind-address = 0.0.0.0,还必须执行UPDATE user SET host='%' WHERE user='root';并FLUSH PRIVILEGES; - 云服务器场景:MySQL 用户的
host必须是'%'或具体公网 IP,'localhost'在远程连接时完全无效
最常被忽略的其实是权限粒度——MySQL 的 host 匹配是精确字符串比对,'user'@'192.168.%' 和 'user'@'192.168.1.%' 是两条不同的权限记录,差一个点就进不去。


















