简体   繁体   English

错误 2002 连接在 PHP 上被拒绝连接到在 MAMP 上运行的 MySQL

[英]Error 2002 Connection refused on PHP connecting to MySQL running on MAMP

I just installed Laravel on my local Mac after installing ddev, Docker and MAMP.在安装 ddev、Docker 和 MAMP 之后,我刚刚在本地 Mac 上安装了 Laravel。 I used https://ddev.readthedocs.io/en/stable/users/cli-usage/#laravel-quickstart guide and everything looked ok.我使用了 https://ddev.readthedocs.io/en/stable/users/cli-usage/#laravel-quickstart指南,一切看起来都不错。 However, when I tried to run a sample code downloaded from the Internet, I started getting the error message但是,当我尝试运行从 Internet 下载的示例代码时,我开始收到错误消息

Illuminate \ Database \ QueryException (2002)照亮\数据库\查询异常(2002)

SQLSTATE[HY000] [2002] No such file or directory (SQL: select * from `users` where `email` = frankie@example.com limit 1)

In the beginning, I thought it was something related to an internal Lavavel error as I saw the email address did not have any quotes.一开始,我认为这与内部 Lavavel 错误有关,因为我看到 email 地址没有任何引号。 However, I tried to connect to MySQL from this PHP script I took from MAMP (section Connect via Network to MySQL )但是,我尝试从我从 MAMP 获取的这个 PHP 脚本连接到 MySQL (通过网络连接到 MySQL部分)

<?php
  $db_host = 'localhost';
  $db_user = 'root';
  $db_password = 'root';
  $db_db = 'information_schema';
  $db_port = 8889;

  $mysqli = new mysqli(
    $db_host,
    $db_user,
    $db_password,
    $db_db
  );
    
  if ($mysqli->connect_error) {
    echo 'Errno: '.$mysqli->connect_errno;
    echo '<br>';
    echo 'Error: '.$mysqli->connect_error;
    exit();
  }

  echo 'Success: A proper connection to MySQL was made.';
  echo '<br>';
  echo 'Host information: '.$mysqli->host_info;
  echo '<br>';
  echo 'Protocol version: '.$mysqli->protocol_version;

  $mysqli->close();
?>

And it was when I realised I cannot connect to MySQL from any PHP script/code run on MAMP (MySQL 5.7.32 ).当我意识到我无法从在 MAMP(MySQL 5.7.32)上运行的任何 PHP 脚本/代码连接到 MySQL 时。 This is the error I got:这是我得到的错误:

Errno: 2002
Error: No such file or directory

Then after reading other similar questions on here, I changed localhost for 127.0.0.1 and got this new message然后在这里阅读了其他类似的问题后,我将localhost更改为127.0.0.1并收到了这条新消息

Errno: 2002
Error: Connection refused

Notes: MySQL is listening on port 8889注意: MySQL 正在监听端口8889

The file /Applications/MAMP/tmp/mysql/mysql.sock exists文件/Applications/MAMP/tmp/mysql/mysql.sock存在

The user and passwords are correct用户名和密码正确

The database also exists数据库也存在

My first thought was about lack of quotation for the email address, that's why I wrote my initial question here SQL/Laravel is not quoting text fields when building a query .我的第一个想法是 email 地址缺少引号,这就是为什么我在这里写了我的初始问题SQL/Laravel is not quoting text fields when building a query However, the real issue is about trying to connect to MySQL server然而,真正的问题是关于尝试连接到 MySQL 服务器

email has to be in apostrophe see When to use single quotes, double quotes, and backticks in MySQL email 必须在撇号中请参阅何时在 MySQL 中使用单引号、双引号和反引号

Like喜欢

select * from `users` where `email` = 'frankie@example.com' limit 1

also i hope you rest of the code use prepared statements with parameters to prevent sql injection我也希望你代码的 rest 使用带有参数的准备好的语句来防止sql 注入

The issue there is that you are not passing the port as the fifth parameter to mysqli connection.问题在于您没有将端口作为第五个参数传递给 mysqli 连接。 If you are using localhost as your host then the port parameter is ignored.如果您使用localhost作为主机,则端口参数将被忽略。 This is why in the MAMP snippet, they are not passing $db_port as a parameter, it simply is not needed.这就是为什么在 MAMP 片段中,他们没有将$db_port作为参数传递,根本不需要它。 The reason this happens, is that localhost does not use TCP/IP, instead it makes use of unix sockets.发生这种情况的原因是localhost不使用 TCP/IP,而是使用 unix sockets。

After you've followed other's suggestion, you've probably changed the code to the point where you had在您遵循其他人的建议之后,您可能已经将代码更改为您所拥有的

$db_host = '127.0.0.1';

This is ok, but since you are no longer using unix sockets ( localhost ), the port parameter is needed in order to establish a connection.这没关系,但是由于您不再使用 unix sockets ( localhost ),因此需要端口参数才能建立连接。 Mysqli uses the 3306 port as default one if you do not specify any other as fifth parameter.如果您不指定任何其他作为第五个参数,Mysqli 使用3306端口作为默认端口。 So that is the port you are trying to connect to by using that code.这就是您尝试使用该代码连接的端口。 This is where the Error: Connection refused comes from.这就是Error: Connection refused的来源。

To solve the issue you just have to pass the port as a fifth parameter like this:要解决此问题,您只需将端口作为第五个参数传递,如下所示:

$mysqli = new mysqli($db_host,$db_user,$db_password,$db_db,$db_port);

The snippet itself is great, it just did not fully suit your needs and you had to do a bit of tweaks to it.片段本身很棒,只是不能完全满足您的需求,您必须对其进行一些调整。 If you want to use snippets you have to understand what they do and in this case how mysqli works.如果您想使用片段,您必须了解它们的作用以及在这种情况下 mysqli 是如何工作的。 Make sure to remember this for the future as it will for sure avoid you unpleasant situations and errors like this one.确保将来记住这一点,因为它肯定会避免像这样的不愉快情况和错误。

After switching to new macbook with m1 chip i got similar issue.在切换到带有 m1 芯片的新 macbook 后,我遇到了类似的问题。 In my particular case i was using nginx + php within docker containers but MySQL was installed on host machine (due to the fact that there is no official docker image for MySQL for M1 chip yet). In my particular case i was using nginx + php within docker containers but MySQL was installed on host machine (due to the fact that there is no official docker image for MySQL for M1 chip yet).

In my application configuration i had following settings:在我的应用程序配置中,我有以下设置:

host: localhost (or 127.0.0.1)
port: 3306
user: root
password: mypassword

And again, in my particular case the application couldn't reach mysql server since PHP was running inside docker container and since i used localhost as a host that was a localhost within PHP container where mysql server is not installed. And again, in my particular case the application couldn't reach mysql server since PHP was running inside docker container and since i used localhost as a host that was a localhost within PHP container where mysql server is not installed.

To solve my problem i changed configuration to this:为了解决我的问题,我将配置更改为:

host: host.docker.internal
port: 3306
user: root
password: mypassword

In the situation of the author of the question, the solution would be to change configuration on:在问题作者的情况下,解决方案是更改配置:

host: db
port: 3306
database: db
user: db
password: db

so host/database/db user/db password - should be set to db as it is said in the documentation here https://ddev.readthedocs.io/en/stable/users/cli-usage/#laravel-quickstart所以 host/database/db 用户/db 密码 - 应该设置为db ,正如这里的文档中所说的https://ddev.readthedocs.io/en/stable/users/cli-usage/#laravel-quickstart

The similar problem could happen if you are using own docker environment with mysql + php + nginx via docker-compose. The similar problem could happen if you are using own docker environment with mysql + php + nginx via docker-compose. Then, if you let's say in your docker-compose.yml file have something like that:然后,如果您在 docker-compose.yml 文件中说这样的话:

mysql:
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: example

Then in you application configuration you should use the following setting to reach mysql server:然后在您的应用程序配置中,您应该使用以下设置来访问 mysql 服务器:

host: mysql
port: 3306
user: root
password: example

So, mysql as a host, since the "service" name of mysql in docker-compose.yml file is set to mysql因此, mysql作为主机,因为 docker-compose.yml 文件中 mysql 的“服务”名称设置为mysql

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM