php 令人困惑的 PDO-only 问题:无法通过套接字连接/拒绝访问/无法连接到服务器(共享主机)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2138959/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 05:11:53  来源:igfitidea点击:

Confusing PDO-only problem : Can't connect through socket/Access denied/Can't connect to server (shared host)

phpmysqlsocketsconnectionpdo

提问by Julien

So the problem changed from what it was, i'll leave the original question below to prevent bad reviews on answers like I had after someone editing his question I answered :

所以问题从原来的样子改变了,我将把原来的问题留在下面,以防止在有人编辑我回答的问题后对答案的负面评论:

So I am working on a (really lame) shared hosting which has PDO installed, but it doesn't work. With default parameters

所以我正在开发一个(非常蹩脚的)共享主机,它安装了 PDO,但它不起作用。使用默认参数

<?php
try {
    $dbh = new PDO('mysql:host=localhost;dbname=THE_DB_NAME', 'THE_USER', 'THE_PASSWORD');
    echo 'Connected to database';
    }
catch(PDOException $e)
    {
    echo $e->getMessage();
    }
?>

it throws this message :

它抛出这个消息:

SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

With a simple mysql_connect, it works.

使用简单的 mysql_connect,它可以工作。

And the socket path seems correct (both phpinfo and this query :

并且套接字路径似乎是正确的(phpinfo 和此查询:

show variables like 'socket';

confirm.

确认。

Localhost redirects to 10.103.0.14 (this data comes from mysql_get_host_info() and in phpMyAdmin)

本地主机重定向到 10.103.0.14(此数据来自 mysql_get_host_info() 和 phpMyAdmin)

In the PDO, if i replace localhost by 127.0.0.1 i will get

在 PDO 中,如果我用 127.0.0.1 替换 localhost 我会得到

SQLSTATE[HY000] [2003] Can't connect to MySQL server on '127.0.0.1' (111) 

And if i replace localhost by 10.103.0.14 :

如果我用 10.103.0.14 替换 localhost :

Access denied for user 'USER_NAME'@'10.103.0.14' (using password: YES

Both IP adress (127.0.0.1 and 10.103.0.14) work with mysql_connect.

IP 地址(127.0.0.1 和 10.103.0.14)都可以与 mysql_connect 一起使用。

So apparently the problem comes from the PDO connection.

所以显然问题来自 PDO 连接。

Does somebody knows where this could come from, or/and any way to fix it ?

有人知道这可能来自哪里,或/和任何解决方法?

Some server datas :

一些服务器数据:

The PHP Version : 5.2.10 You can see the server's phpinfo : http://web.lerelaisinternet.com/abcd.php?v=5No command line possible. (i know it should be the tech suport's job, but they're reaaaaaly slow)

PHP 版本:5.2.10 您可以看到服务器的 phpinfo:http://web.lerelaisinternet.com/abcd.php? v=5没有命令行可能。(我知道这应该是技术支持的工作,但他们真的很慢)

Thanks

谢谢

Previous question :

上一个问题:

How to find the mysql.sock on a shared host (tricky way needed...)

如何在共享主机上找到 mysql.sock(需要棘手的方法......)

So today's problem is : The PDO connection doesn't work on a shared host, and it's supposed to (it's installed on the server). Just a basic PDO connection :

所以今天的问题是:PDO 连接在共享主机上不起作用,它应该(它安装在服务器上)。只是一个基本的 PDO 连接:

<?php
try {
    $dbh = new PDO('mysql:host=localhost;dbname=THE_DB_NAME', 'THE_USER', 'THE_PASSWORD');
    echo 'Connected to database';
    }
catch(PDOException $e)
    {
    echo $e->getMessage();
    }
?>

throws this message :

抛出此消息:

SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)

A regular mysql connection :

一个常规的 mysql 连接:

mysql_connect("localhost", "THE_USER", "THE_PWD") or die(mysql_error()); 
mysql_select_db("24DLJLRR1") or die(mysql_error());;
echo 'Connected to database <br/>';

works fine.

工作正常。

So apparently it cannot find the .sock. I think specifying the correct address should work, i tried some "classic" mysql path that I found on internet, without success. The phpinfo says it is at this adress (/var/lib/mysql/mysql.sock) (The PHP Version is 5.2.10) You can see the server's phpinfo : http://web.lerelaisinternet.com/abcd.php?v=5

所以显然它找不到.sock。我认为指定正确的地址应该有效,我尝试了一些我在互联网上找到的“经典”mysql 路径,但没有成功。phpinfo 说它在这个地址 (/var/lib/mysql/mysql.sock) (PHP 版本是 5.2.10) 你可以看到服务器的 phpinfo : http://web.lerelaisinternet.com/abcd.php? v=5

So i am trying to figure out where the hell it is !!! I tried to look in the phpMyAdmin interface, but i couldn't find the info, plus it seems that phpMyAdmin connects to a different server (it has a different IP adress, and trying to connect to it with php gives a "Wrong password" error). The mysql_connect also connects to this adress, i think it redirects to a different server with some internal password/login.

所以我想弄清楚它到底在哪里!!!我试图查看 phpMyAdmin 界面,但我找不到信息,而且 phpMyAdmin 似乎连接到不同的服务器(它具有不同的 IP 地址,并尝试使用 php 连接到它会给出“错误的密码”)错误)。mysql_connect 也连接到这个地址,我认为它使用一些内部密码/登录重定向到不同的服务器。

Well if you have any idea of how to obtain this info (the provider's technical support is "fixing the problem"... it's been 1 month...). Also maybe the problem comes from somewhere else, but the same stuff works on other shared hosts...

好吧,如果您对如何获取此信息有任何想法(提供商的技术支持正在“解决问题”...已经 1 个月了...)。也可能问题来自其他地方,但同样的东西也适用于其他共享主机......

The need of PDO is because I use the Symfony framework with Doctrine for this website, and the Doctrine plugin needs PDO... I don't want to redo the website from scratch !

需要PDO是因为我这个网站用的是Symfony框架和Doctrine,而Doctrine插件需要PDO...我不想从头开始重做网站!

Thanks for your help !

谢谢你的帮助 !

采纳答案by Julien

One year later, I found a solution for this issue : using a SQLite database. PDO worked fine, but not with MySQL

一年后,我找到了解决此问题的方法:使用 SQLite 数据库。PDO 工作正常,但不适用于 MySQL

** EDIT ** as everyone is downvoting this: This solved my issue (I'm the OP). I was using Doctrine, so switching RDBMS was easy and quick. Also the website was some a home made CMS, with very few trafic, so SQLite was fine.

** 编辑 ** 因为每个人都反对这个:这解决了我的问题(我是 OP)。我使用的是 Doctrine,因此切换 RDBMS 既简单又快捷。此外,该网站是一些自制的 CMS,流量很少,所以 SQLite 很好。

I know it's not a real "Answer" to the problem, but if someone is in the same context: a crappy shared hosting which you can't change with this weird PDO-MySQL bugAND is using doctrine. This IS a solution. I can delete this answer, but if I had thought of this at the time of the OP, I would have saved a lot of time.

我知道这不是问题的真正“答案”,但是如果有人处于相同的上下文中:一个糟糕的共享主机,你不能用这个奇怪的 PDO-MySQL 错误来改变它并且正在使用学说。这是一个解决方案。我可以删除这个答案,但如果我在 OP 的时候想到了这一点,我会节省很多时间。

回答by Brent

This was already marked as answered, but not really solved (without changing databases). So, just in case someone like me also experiences this problem...

这已经被标记为已回答,但并未真正解决(不更改数据库)。所以,以防万一像我这样的人也遇到这个问题......

The easiest way to fix this is to first get the socket path (either by looking in the php.ini file or by using: phpmyadmin or the console (or construct it in mysql or mysqli)

解决此问题的最简单方法是首先获取套接字路径(通过查看 php.ini 文件或使用:phpmyadmin 或控制台(或在 mysql 或 mysqli 中构建)

...to run the following query (anything but PDO):

...运行以下查询(除了 PDO 之外的任何内容):

show variables like 'socket';       //as mentioned by symcbean

THEN, in the PDO connection string, change it to use the socket instead of a hostname:

然后,在 PDO 连接字符串中,将其更改为使用套接字而不是主机名:

$dbc = new PDO("mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=$DBName", $User, $Password, array(PDO::ATTR_PERSISTENT => true)); // using persistent connections

$dbc = new PDO("mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=$DBName", $User, $Password, array(PDO::ATTR_PERSISTENT => true)); // 使用持久连接

This worked for me.

这对我有用。

回答by zmonteca

FWIW, I had this issue and changed my host from 'localhost' to '127.0.0.1'.

FWIW,我遇到了这个问题并将我的主机从“localhost”更改为“127.0.0.1”。

I have no clue why localhost wasn't working, but that did the trick.

我不知道为什么 localhost 不起作用,但这确实有效。

Odd thing is, we have tons of servers and it works on almost every one using 'localhost'

奇怪的是,我们有大量的服务器,它几乎可以在每个使用“本地主机”的服务器上运行

回答by Rodrigo Renie

Is your server running with SeLinux enabled (enforcing)? If it is, try running as root:

您的服务器是否在启用(强制执行)SeLinux 的情况下运行?如果是,请尝试以 root 身份运行:

# setsebool -P httpd_can_network_connect on

回答by Valentin Rusk

I had the problem that production version worked just fine and a test version wasn't able to connect PDO :/ both versions was located at same servers, test in a sub directory.

我遇到的问题是生产版本运行良好,测试版本无法连接 PDO:/ 两个版本都位于相同的服务器上,在子目录中测试。

The fix was replacing in DSN the localhost for ip.

修复是在 DSN 中将 localhost 替换为 ip。

'mysql:host=localhost;dbname=db'

became

变成了

'mysql:host=127.0.0.1;dbname=db'

回答by Pekka

Can you try 127.0.0.1as the server name instead of localhost?

您可以尝试127.0.0.1作为服务器名称而不是localhost?

IIRC, with some mySQL drivers / adapters, this decides whether the socket is used for establishing the connection or not.

IIRC,使用一些 mySQL 驱动程序/适配器,这决定了套接字是否用于建立连接。

回答by symcbean

Using the connection which works, run the query:

使用有效的连接,运行查询:

show variables like 'socket';

(this behaves just like a select statement)...and you'll get the path of the running socket.

(这就像一个选择语句)......你会得到正在运行的套接字的路径。

Then check the file permissions.

然后检查文件权限。

回答by Rufinus

try:

尝试:

exec('`which mysql_config` --socket');

this should show you the configured socket.

这应该向您显示配置的套接字。

回答by Franz

I found the reason for the strange behaviour. If bind-address is different to 127.0.0.1 or 0.0.0.0 (all addresses) PDO can't connect to 127.0.0.1.

我找到了奇怪行为的原因。如果绑定地址与 127.0.0.1 或 0.0.0.0(所有地址)不同,则 PDO 无法连接到 127.0.0.1。

回答by phpguru

For what it's worth, I found this page after having the exact same issue. I am on a server running Apache & PHP only - MySQL is installed on another machine. I tried both the DNS name of the server and its IP and confirmed I could ping it. A PHP app on the same machine is talking to the database fine, using old syntax mysql_connect( ). But PDO from the CLI was throwing this error.

对于它的价值,我在遇到完全相同的问题后找到了这个页面。我在一台只运行 Apache 和 PHP 的服务器上 - MySQL 安装在另一台机器上。我尝试了服务器的 DNS 名称及其 IP,并确认我可以 ping 通它。同一台机器上的 PHP 应用程序使用旧语法 mysql_connect() 与数据库正常通信。但是来自 CLI 的 PDO 抛出了这个错误。

The solution for me was to check my DSN. Any typo in the DSN itself is ignored silently, and PDO assumes you mean localhost. My issue was I had "name=" instead of "dbname=" in the DSN.

我的解决方案是检查我的 DSN。DSN 本身中的任何错字都会被静默忽略,并且 PDO 假定您的意思是 localhost。我的问题是我在 DSN 中有“name=”而不是“dbname=”。

回答by Nick Res

What worked for me was specifying the port number like so:

对我有用的是指定端口号,如下所示:

mysql:hostname;port=3306;dbname=dbname;

mysql:hostname;port=3306;dbname=dbname;

This got it to work when connecting to a local database. Now I'm working on getting it to work with a remote db.

这使它在连接到本地数据库时起作用。现在我正在努力让它与远程数据库一起工作。