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

Posted

技术标签:

【中文标题】令人困惑的仅 PDO 问题:无法通过套接字连接/访问被拒绝/无法连接到服务器(共享主机)【英文标题】:Confusing PDO-only problem : Can't connect through socket/Access denied/Can't connect to server (shared host) 【发布时间】:2011-01-09 11:38:19 【问题描述】:

所以问题改变了原来的问题,我将把原来的问题留在下面,以防止在有人编辑我回答的问题后对我的答案产生差评:

所以我正在开发一个安装了 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();
    
?>

它抛出这个消息:

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

通过一个简单的 mysql_connect,它就可以工作了。

而且套接字路径似乎是正确的(phpinfo 和这个查询:

show variables like 'socket';

确认。

Localhost 重定向到 10.103.0.14(此数据来自 mysql_get_host_info() 和 phpMyAdmin)

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

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

如果我将 localhost 替换为 10.103.0.14 :

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

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

显然问题出在 PDO 连接上。

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

一些服务器数据:

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

谢谢

上一个问题:

如何在共享主机上找到 mysql.sock(需要技巧...)

所以今天的问题是: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();
    
?>

抛出此消息:

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

一个常规的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/>';

工作正常。

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

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

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

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

感谢您的帮助!

【问题讨论】:

可能是套接字存在,但您没有访问它的必要权限。无论如何,这不是您的提供商技术支持的问题吗? 我猜它在那里工作!他们太蹩脚了,我们已经等了一个多月了,加上它在法国,需要 30 分钟才能找到合适的人。问题是它是一个重要客户,我们必须发货......(该网站现在正在镜像,但我们客户希望它在他的主机上,它属于法国电信公司,所以我们不能说它很蹩脚)。此外,我们不能直接与服务器技术支持交谈。那我怎么没有权限访问它呢?我的意思是如果安装了 PDO 并且我可以通过 mysql_connect 进行连接,我应该没有它们? 据我了解,您不走运。映射的本地主机到不同的 ip。但似乎 mysql 服务器本身只允许从 localhost 访问(在他们的情况下解析为您的 10.103.0.14)。如果主机是 localhost,pdo 似乎使用套接字。 (请参阅 php.net 文档,pdo - connection second comment)但是为什么 mysql_connect 与 127.0.0.1 一起工作很奇怪。在这种情况下 pdo connect with host=127.0.0.1 应该也可以工作。 【参考方案1】:

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

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

...运行以下查询(除了 PDO):

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

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

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

这对我有用。

【讨论】:

谢谢你,这就像一个魅力!这应该是公认的答案!【参考方案2】:

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

我不知道为什么 localhost 不工作,但这成功了。

奇怪的是,我们有大量的服务器,它几乎可以在每个使用 'localhost' 的服务器上运行

【讨论】:

这里也一样。如果您知道原因,请在 gplus.to/swader 上给我留言。我的主机文件设置为将 127.0.0.1 定向到 localhost,所以没关系。奇数。 我在服务器上看到了同样的错误,此时有第二个 mysql-server 处于活动状态(ps aux | grep mysql)......通过“127.0.0.1”的连接仍然有效,但通过“localhost”(unix-socket)不起作用:“无法通过套接字连接到本地 MySQL 服务器 ...”-> 我们必须“杀死 -9”并重新启动 mysql:/【参考方案3】:

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

# setsebool -P httpd_can_network_connect on

【讨论】:

【参考方案4】:

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

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

【讨论】:

我得到一个不同的错误:SQLSTATE[HY000] [2003] Can't connect to MySQL server on '127.0.0.1' (111) 是否有一个 mySQL 服务器在 localhost 上运行?你确定吗? 啊,对不起,你上面说有。 这有点令人困惑,因为 mysql_get_host_info() 函数给了我一个 IP 地址(10.103.0.14),所以不是 10.0.0.127。如果我从 PDO 尝试这个 IP 地址,我会得到:用户 'USER_NAME'@'10.103.0.14' 的访问被拒绝(使用密码:YES) 我已经开始感觉到您的提供商正在将 localhost 映射到不同的 IP(虽然还不确定)。你可以试试我对 symcbean 的回答的评论吗?【参考方案5】:

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

show variables like 'socket';

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

然后检查文件权限。

【讨论】:

+1 上面引用的套接字路径肯定不存在(错误 2 = 没有这样的文件或目录)。这听起来是最好的方法。 非常感谢!现在的问题是我得到:数组( [0] => socket [1] => /var/lib/mysql/mysql.sock ),所以套接字在正确的位置......我想我要去杀了我自己。如何检查文件权限? (我认为应该有,如果它与 mysql_connect 一起使用)也许这只是他们的 PDO 安装的问题...... 我认为mysql_connect 连接没有使用套接字,这就是它起作用的原因。开个玩笑,如果在工作的 mysql 连接中将localhost 替换为127.0.0.1 会发生什么? 这很奇怪。我认为 PDO 使用与经典 mysql_connect() 不同的客户端库,但这里有一些不同的错误......我不知道这可能是什么。 是的,我越来越困惑了,我改变了话题,因为套接字似乎在正确的位置......希望有人知道。我不想创建一个新问题,因为 cmets 中有很多元素,但如果没有人回答,我会将此标记为正确答案(因为它让我发现套接字在正确的位置.. .)【参考方案6】:

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

修复是在 DSN 中替换 localhost 的 ip。

'mysql:host=localhost;dbname=db'

成为

'mysql:host=127.0.0.1;dbname=db'

【讨论】:

是的。修复它但是为什么? Ping localhost 给了我 127.0.0.1 作为 IP 那么为什么不能使用 localhost 呢?? 机器上的主机解析似乎有问题。【参考方案7】:

尝试:

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

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

【讨论】:

如果他可以运行外部程序,好主意。对于任何 mysql.sock 文件,find 也可能是一个想法。 看来我做不到 【参考方案8】:

我找到了奇怪行为的原因。如果 bind-address 不同于 127.0.0.1 或 0.0.0.0(所有地址),PDO 无法连接到 127.0.0.1。

【讨论】:

【参考方案9】:

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

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

【讨论】:

【参考方案10】:

Mysql配置中的问题 需要禁用skip-networking的选项 在 my.conf 配置文件中,这应该可以正常工作 参考 http://www.wolfcms.org/forum/post7098.html#p7098

【讨论】:

【参考方案11】:

我刚刚解决了一个类似的问题。我的猜测是你可能用 PDO 等效替换了你的 mysql_connect() 语句。不要忘记您仍然有许多其他代码依赖于旧的连接语句。在编写 PDO 代码时尝试保持 mysql_connect 就位。

【讨论】:

【参考方案12】:

对我有用的是像这样指定端口号:

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

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

【讨论】:

【参考方案13】:

我的问题可能与 OP 不同,但我认为值得发布。我在 VM 上进行了软件升级,然后重新启动并收到 OP 的错误消息。原来是内存不足问题导致mysql无法启动。删除几个大文件后问题就消失了。

【讨论】:

【参考方案14】:

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

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

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

【讨论】:

这对我有用,但布伦特的选项看起来更有趣 您对 OP 的解决方案是切换 RDBMS? IMO 这不是解决方案。 当OP问题仍然存在时不是解决方案 好吧,我被卡住了,客户很生气,我的老板对我大喊大叫。我切换了 RDBMS,现在客户很高兴,我的老板也在微笑。所以我想这可以称为解决方案。 这是商业解决方案,不是技术解决方案。

以上是关于令人困惑的仅 PDO 问题:无法通过套接字连接/访问被拒绝/无法连接到服务器(共享主机)的主要内容,如果未能解决你的问题,请参考以下文章

我无法实现与 mysql db 的 PDO 连接

TensorFlow 2 中的堆叠双向 RNN 令人困惑

将 Rollup、ES 模块、TypeScript 和 JSX 连接在一起时的令人困惑的行为

不要通过 PDO 连接 oracle 数据库和 PHP

PDO dblib 无法将 ip 地址作为“主机”参数连接

Python套接字没有正确关闭连接