当无法访问服务器时,PHP 的 PDO 将忽略 MySQL 的 ATTR_TIMEOUT 选项

2022-01-24 00:00:00 connection php mysql pdo

我正在测试无法通过输入随机 IP 来尝试连接到 mysql 服务器的场景.我使用 PDO::ATTR_TIMEOUT => 将 PDO 的选项设置为在一秒钟后超时1.但是,抛出异常仍然需要 30 秒.我猜这个超时只适用于实际的mysql连接时间,而不适用于运行mysql的服务器.

I'm testing scenarios where the mysql server cannot be reached by putting in a random IP to try to connect to. I set PDO's options to time out after one second using PDO::ATTR_TIMEOUT => 1. However, it still takes 30 seconds to throw an exception. I'm guessing this timeout only applies to the actual mysql connection time, not to the server on which mysql is running.

我需要更改哪些 PHP 选项以使与 mysql 服务器的连接超时?

What PHP options do I need to change to time out the connection to the mysql server?

推荐答案

随便放

ini_set("default_socket_timeout", 2);

在您的 PDO() 连接字符串之前.

before your PDO() connect string.

(在 Windows 上测试,在 Linux 上也应该没问题.)

(Tested on Windows, should also be fine on Linux.)

为什么?

通过手册追查这个:

mysqlnd 驱动程序使用套接字进行底层连接,而要设置超时,您需要使用套接字(流)超时函数.(参考:http://php.net/manual/en/mysqlnd.notes.php)

The mysqlnd driver uses sockets for the underlying connection, and that to set timeouts you need to use the socket (stream) timeout functions. (Ref: http://php.net/manual/en/mysqlnd.notes.php)

使用 mysqlnd 意味着使用 PHP 流进行底层连接.对于 mysqlnd,应参考 PHP 流文档 (Streams) 的超时设置等详细信息,而不是 MySQL 客户端库的文档.

Using mysqlnd means using PHP streams for underlying connectivity. For mysqlnd, the PHP streams documentation (Streams) should be consulted on such details as timeout settings, not the documentation for the MySQL Client Library.

<小时>

如果你想要更多的控制,那么你可以更具体地控制实际的套接字:我没有测试过这个,因为它只是 unix.要设置 mysqlnd 使用的套接字,您可以使用 ini 设置指定套接字(参考:http://php.net/manual/en/ref.pdo-mysql.connection.php)

如果 PDO_MYSQL 是针对 mysqlnd 编译的,则可以通过 pdo_mysql.default_socket 设置设置默认套接字.

If PDO_MYSQL is compiled against mysqlnd a default socket can be set thru the pdo_mysql.default_socket setting.

参见 http://php.net/manual/en/ref.pdo-mysql.php#ini.pdo-mysql.default-socket 关于该设置

然后您可以使用 http://php.net/manual 设置超时/en/function.stream-set-timeout.php

但可能更容易设置默认值,然后在完成后重置...

But probably easier to set default and then reset once you're done...

相关文章