Rootop 服务器运维与web架构

SQLSTATE[HY000] [2002] No such file or directory

在访问项目的时候报错:

SQLSTATE[HY000] [2002] No such file or directory

首先这是用pdo连接的mysql数据库,框架是thinkphp5,其实知道问题在哪里,但是要知道原理是什么。

讲一下知识点:
连接mysql时候php连接参数一般两种,localhost和127.0.0.1或者其他ip地址或域名。
区别为:
localhost 通过socket通讯也就是mysql.sock,在php.ini中默认配置如下。

127.0.0.1 是通过tcp/ip通信。也就是通过ip地址连接。

如果用localhost,需要修改php.ini指向正确的mysq.sock路径.
比如:

pdo_mysql.default_socket=/tmp/mysql.sock # 这个路径是由数据库的my.cnf中配置的

如果你用的是虚拟主机,接触不到php的配置文件,那么只需要把localhost改为127.0.0.1,或者改为平台商提供给你的数据库连接地址,
一般为域名,比如 rootop-db.hk.mysql.rootop.org 这种域名式的地址

来看一下为什么会出这个错误。
通过phpinfo可以看到当前php中的mysql.sock路径,如图。

我现在把mysql的sock文件修改为如下:

[client]
port            = 3306
socket          = /var/tmp/mysql.sock

[mysqld]
port            = 3306
socket          = /var/tmp/mysql.sock

重启mysql

[root@MiWiFi-R3P-srv ~]# ll /var/tmp/mysql.sock
srwxrwxrwx 1 mysql mysql 0 3月   8 20:11 /var/tmp/mysql.sock

新的路径已经生效,但是php里默认还是在/tmp下,这时,我们用localhost去连接数据库。
tp的连接数据库代码如下图。

页面报错如下:

因为找不到sock文件,所以页面报错。修改为127.0.0.1,就可以正常获取数据库中的数据了,因为他不走socket连接了。

那么就想用localhost怎么办呢?
1、修改php.ini,改为正确的mysql.sock路径(方法上面已经提过了)。
2、修改连接参数地址改为 localhost:3306
如图

发现也可以获取数据,为什么改为localhost:3306也可以?因为在后面加上:3306后,就不代表用localhost(socket)的方式去连接了。
实际在连接数据库的时候,会把localhost解析为127.0.0.1,也就是通过ip方式访问了。
等于
localhost = socket方式连接
localhost:3306 = ip方式连接
127.0.0.1 = ip方式连接

看看原生php连接数据库

报错如下:

改为localhost:3306后可以获取。
这里有个有意思的地方就是,不管原生写法还是tp框架,当host为localhost时,port参数就没用了,因为走socket,当为localhost:3306时,port参数也没有用,只有当地址为127.0.0.1或其它ip时(不带端口号),后面的port参数才有效。

参考:
php pdo文档:https://www.php.net/manual/en/ref.pdo-mysql.connection.php

原创文章,转载请注明。本文链接地址: https://www.rootop.org/pages/4686.html

作者:Venus

专注于 服务器运维与web架构 E-mail:venus#rootop.org

评论已关闭。