PHP PDO连接MySQL报错SQLSTATE[HY000] [2002] Connection refused求助
PDO Connection Refused When Connecting to MySQL Docker Container (Works in PhpStorm)
我在Docker环境中使用PHP Data Objects (PDO)连接MySQL数据库时遇到了连接拒绝的问题,但通过PhpStorm使用相同的用户名和密码却能正常连接。以下是我的具体环境和问题细节:
环境信息
- PHP 7.1.16(Docker容器)
- Nginx 1.13.12-1(Docker容器)
- MySQL 8.0.11-1debian9(Docker容器)
通过phpinfo()确认已加载的PDO驱动:
- sqlite(SQLite Library 3.15.1)
- mysql(mysqlnd 5.0.12-dev)
我的PHP代码
<?php $serverName = "127.0.0.1"; $port = "3306"; $dbName = "callitTime"; $userName = "root"; $password = "superstrongPassword"; try { $db = new PDO("mysql:host=$serverName;dbname=$dbName;port=$port;", $userName, $password); } catch (PDOException $pdoE) { echo 'An Error occurred: ' . $pdoE->getMessage(); } ?>
错误信息
An Error occurred: SQLSTATE[HY000] [2002] Connection refused
PhpStorm可以正常连接,但PHP脚本始终报错,请问该如何解决?
解决方案
这个问题我之前在Docker环境里也碰到过,大概率是Docker容器网络隔离和MySQL 8.0认证插件兼容性这两个原因导致的,咱们一步步来搞定:
1. 先修复容器间的网络访问问题
Docker里每个容器都是独立的小环境,你PHP脚本里写的127.0.0.1,在PHP容器里指的是它自己,不是MySQL容器哦!所以得把主机名换成MySQL容器的服务名或者容器IP:
怎么获取MySQL容器的服务名/IP?
- 如果你是用
docker-compose部署的,直接用docker-compose.yml里MySQL服务的名字(比如一般会写mysql)当主机名就行 - 要是单独启动的容器,执行这条命令查IP:
docker inspect <你的MySQL容器名> | grep IPAddress
修改后的PDO连接代码示例:
// 假设MySQL容器的服务名叫mysql $db = new PDO("mysql:host=mysql;dbname=$dbName;port=$port;", $userName, $password);
2. 解决MySQL 8.0的认证插件兼容问题
PHP 7.1的mysqlnd驱动对MySQL 8.0默认的caching_sha2_password认证插件支持不好,这也会导致连接被拒。咱们得把root用户的认证方式改成老的mysql_native_password:
操作步骤:
- 先进入MySQL容器:
docker exec -it <你的MySQL容器名> mysql -u root -p
- 然后执行这两条SQL:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'superstrongPassword'; FLUSH PRIVILEGES;
小贴士:
'root'@'%'是允许root从任何地方连接,如果你之前设置了特定主机,记得换成对应的主机名或者IP哦
3. 最后检查两个小细节
- 确认PHP容器和MySQL容器在同一个Docker网络里(不管是默认的bridge还是你自己建的自定义网络),不在同一个网络的话,容器之间是没法通信的
- 要是你用了端口映射,确认MySQL容器的3306端口确实开启,但其实容器间通信不需要端口映射,只要在同一个网络就没问题
做完这些之后,再跑你的PHP脚本试试,应该就能顺利连接上数据库啦!
内容的提问来源于stack exchange,提问作者LastSgt
相关产品推荐
相关产品推荐

