PHP连接失败:SQLSTATE [HY000] [2002]连接被拒绝。

79

我正在尝试使用PHP连接到phpmyadmin上的MySQL数据库。连接没有什么特别之处,只是想看看连接是否成功。我正在使用MAMP来托管数据库,我尝试使用的连接如下:

<?php
$servername = "127.0.0.1";
$username = "root";
$password = "root";

try {
    $conn = new PDO("mysql:host=$servername;dbname=AppDatabase", $username, $password);
    // set the PDO error mode to exception
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "Connected successfully"; 
}
catch(PDOException $e)
{
    echo "Connection failed: " . $e->getMessage();
}
?>

我一直在使用Postman测试连接是否正常,但是一直收到以下错误消息:

连接失败:SQLSTATE[HY000] [2002] 连接被拒绝

之前我收到的错误消息是:

连接失败:SQLSTATE[HY000] [2002] 没有这个文件或目录

这是因为我将服务器名称设置为本地主机名(localhost),更改为IP地址后,它给了我一个拒绝连接的错误,我不知道出了什么问题。

如果您能提供任何帮助,将不胜感激。


听起来你的MySQL服务没有在127.0.0.1 TCP上监听。如果它实际上正在运行,可能是它在本地套接字上而不是TCP上。mysql:localhost;dbname=AppDatabase 有区别吗? - Michael Berkowski
...或者是在“localhost”上发生了“没有这个文件或目录”的情况?如果是这种情况,要么是php.ini中的套接字路径不正确,要么是MySQL根本没有运行。 - Michael Berkowski
如果有人因为和我一样的原因遇到了这个问题,那么我的问题是我在代码中犯了一个错误,导致我使用错误的主机名登录到数据库中。 - Donald Duck
1
您在使用MySQL时可能会遇到磁盘空间不足的相同错误。如果您在使用Ubuntu操作系统,请使用命令$ df -h检查磁盘空间。 - Sadee
10个回答

69

我找到了连接无法工作的原因,那是因为连接尝试连接到8888端口,而应该连接到8889端口。

$conn = new PDO("mysql:host=$servername;port=8889;dbname=AppDatabase", $username, $password); 

这解决了问题,不过将服务器名称更改为“localhost”仍然会出现错误。

连接失败:SQLSTATE[HY000] [2002] 没有该文件或目录

但是当输入服务器的IP地址时,它可以成功连接。


1
尝试执行 ping localhost 命令,以查看是否可以将其 ping 到环回地址。可能是您的 hosts 文件已损坏。无论如何,使用主机名而非 IP 地址会提供轻微的性能提升。 - DarkBee
4
你是如何找出正确的端口的?默认情况下本地主机端口是8080吗?当你使用TCP协议时会改变吗? - Pasha Skender
我相信这与ipv6有关。对于我来说,主机localhost解析为::1,因此我怀疑底层的mysql客户端没有ipv6支持(即使是本地地址)。像答案的最后一行建议的那样将其更改为127.0.0.1解决了我的问题。 - Tit Petric
在使用 Laradock.io( Laravel 8)时,我遇到了同样的错误消息,然而后来我需要更新它以使用我的真实 IP 地址来解决它。我猜这是因为代码访问是在 Docker 容器内完成的。 - olle.holm

15

我花了相当多的时间在一个docker环境中,其中所有的容器都是docker容器,我使用Phinx进行迁移。只是为了分享不同配置的不同响应。

可行解决方案

"host" => "db", // {docker container's name} Worked
"host" => "172.22.112.1", // {some docker IP through ipconfig - may change on every instance - usually something like 172.x.x.x} Worked

无法解决的方案

"host" => "127.0.0.1", // SQLSTATE[HY000] [2002] Connection refused
"host" => "docker.host.internal", //  SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name does not resolve
"host" => "localhost", //  SQLSTATE[HY000] [2002] No such file or directory

我是这样运行Phinx的。

docker compose --env-file .env run --rm phinx status -e development

3
实际上,对我来说,将本地主机更改为服务名称是可以的。 - Csharls
1
一样!这节省了我很多时间。 - David
1
非常感谢您提供的示例,我的示例与Docker容器的名称配合使用成功了 :-) 不过必须删除 'port' 选项。 - javier_domenech

7

在我的情况下,MySQL服务器没有运行。我重新启动了MySQL服务器,问题得到了解决。

//on ubuntu server
sudo /etc/init.d/mysql start

为了避免MySQL停止的问题,您可以在Ubuntu 14.04 LTS Linux中使用“initctl”实用程序,以确保在发生故障或重新启动时服务重新启动。为了保留数据,请考虑在执行此操作之前(停止mysql)对根卷进行快照[8]。您可以使用以下命令使用“initctl”实用程序管理MySQL服务,并执行停止和启动操作。
$ sudo initctl stop mysql
$ sudo initctl start mysql

为了验证其工作状态,您可以检查服务的状态并获取进程ID(PID),通过以下命令杀死“mysql”进程来模拟故障,并在一段时间后(通常在1分钟内)验证其状态是否为运行中,并获得新的进程ID。

$ sudo initctl status mysql         # get pid
$ sudo kill -9 <pid>                # kill mysql process
$ sudo initctl status mysql         # verify status as running after sometime

注意:在最新的Ubuntu版本中,initctl被systemctl所取代


那么你对连接失败错误的原因有什么答案?看起来这是在讲解如何启动和停止MySQL服务,可能错过了相关内容。 - oemb1905
请检查我的第一行,我清楚地表明,在我的情况下,服务器自动停止,而我并不知道。因此,为了解决服务器停止的问题,我只是使用了上述语句来防止意外的服务器停机问题。希望这有意义。 - vinod
当然,这很容易看出来,但是由于它没有涉及错误代码或无法连接到数据库的问题,所以似乎是另一个问题。昨晚我来到这里调试mariadb实例上的一些问题,并花了大约5分钟时间阅读你的帖子,看看是否有遗漏的东西,但只是告诉人们如何启动/停止服务,而不是为什么在确认服务正在运行时可能会出现这些错误,就像OP的情况一样。通常,为了帮助读者,提供答案的人会在帖子顶部注明与问题无关。 - oemb1905

3
使用MAMP,我将host=localhost更改为host=127.0.0.1。但是出现了一个新问题"connection refused"

通过在'Datasources' => [中添加'port' => '8889'来解决这个问题。


2

1. 服务器证书验证标志

我需要使用SSL连接,并且需要在new PDO选项数组中设置PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT为false,除了条目PDO::MYSQL_ATTR_SSL_CA用于CA文件。

如果没有它,在服务器上的mysql日志中将会提到:

2021-07-27 17:02:51 597605 [Warning] Aborted connection 597605 to db: 'unconnected' user: 'unauthenticated' host: '192.168.10.123' (This connection closed normally without authentication)

我确定在DSN中传递了正确的数据库和用户名等信息,但出现了空选项数组的错误,至少会在错误日志中显示数据库和用户。我相信这些事情有一个有效的技术原因。
我添加这些信息是为了下次更容易找到它。

2. 连接字符串中的主机

在SSL的上下文中,如果证书中使用的是主机名作为CN(通用名称),则使用IP地址而不是主机名进行连接时也会出现错误。


1
在Mac上使用MAMP时,我通过重命名解决了我的问题。
/Applications/MAMP/tmp/mysql/mysql.sock.lock

to

/Applications/MAMP/tmp/mysql/mysql.sock

0

我在一个来自php:8.0-fpm-alpine镜像的docker容器上遇到了同样的问题。我只需要在Dockerfile中添加以下行,就解决了这个问题:

RUN apk add mysql-client

0
对我来说,问题出在使用了 Mac 自带的 PHP 版本而非 MAMP。.bash_profile 文件中的 PATH 变量设置错误。我只需将 MAMP 的 PHP 二进制文件夹添加到 $PATH 环境变量即可解决问题。对我来说,正确的设置是:
/Applications/mampstack-7.1.21-0/php/bin
  1. 在终端中运行 vim ~/.bash_profile 打开 ~/.bash_profile 文件

  2. 输入 i 以编辑文件,在文件顶部添加 bin 目录作为 PATH 变量:

    export PATH="/Applications/mampstack-7.1.21-0/php/bin/:$PATH"

  3. 按下 ESC,输入 :wq,然后按下 Enter

  4. 在终端中运行 source ~/.bash_profile
  5. 在终端中输入 which php,输出应该是 MAMP PHP 安装的路径。

-1

我曾经遇到过类似的问题,结果发现数据库中的用户是这样创建的:

CREATE USER 'webpage'@'localhost' IDENTIFIED BY 'password';

当连接细节的php脚本中有localhost时,一切都很好,但当IP地址出现时就不行了。快速交换(在创建用户时使用IP地址,在连接细节中使用localhost)揭示了这两个事情必须匹配。


如果您有新的问题,请通过单击提问按钮来提出。如果它有助于提供上下文,请包含此问题的链接。- 来自审核 - ORHAN ERDAY

-4

如果你仍然在与拒绝连接的问题苦苦挣扎,这里有一个建议。下载XAMPP或其他类似的软件,只需启动MySQL即可。你不必运行apache或其他东西,只需要运行MySQL。


安装其他软件如何解决给定的问题?如果已安装了XAMPP,同样的问题会发生吗? - Nico Haase

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接