【问题标题】:Why mysqli_connect doesn't respect MYSQLI_OPT_CONNECT_TIMEOUT?为什么 mysqli_connect 不尊重 MYSQLI_OPT_CONNECT_TIMEOUT?
【发布时间】:2021-02-27 08:36:03
【问题描述】:

下面的代码将停留在real_connect() 100%。 set_time_limitdefault_socket_timeoutMYSQLI_OPT_CONNECT_TIMEOUT 已设置,但不起作用。

我在 PHP 5.6 和 PHP 7.1 上进行了测试。 mysql驱动是mysqlnd。

set_time_limit(30);
ini_set('default_socket_timeout', 10);
$mysql = new mysqli();
$mysql->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5);
$mysql->real_connect('www.baidu.com', 'root', 'xxx', 'xxx', 80);

问题:

  1. 为什么使用主机地址www.baidu.com和端口号80时PHP进程卡在real_connect
  2. 为什么MYSQLI_OPT_CONNECT_TIMEOUT 和其他超时设置不起作用?
  3. 对于这种特殊情况,是否有任何方法可以设置超时?

【问题讨论】:

  • 嗯,mysql 运行在 3306 端口而不是 80 端口。
  • @AlexBarker 我知道。我只想知道为什么PHP在使用主机地址“www.baidu.com”和端口号“80”时卡在real_connect上,虽然我设置了超时
  • 也设置MYSQLI_OPT_READ_TIMEOUT

标签: php mysql mysqli timeout


【解决方案1】:

我找到了原因。在我的情况下,超时是读取超时,而不是连接超时。因此MYSQLI_OPT_CONNECT_TIMEOUT 不起作用。解决方法是在php.ini文件中设置mysqlnd.net_read_timeout。参数值以秒为单位。如: mysqlnd.net_read_timeout = 3

【讨论】:

    【解决方案2】:

    有两种超时设置。一个是MYSQLI_OPT_CONNECT_TIMEOUT,另一个是MYSQLI_OPT_READ_TIMEOUT。第二个文档记录不充分,但可以通过两种方式设置此选项。

    使用mysqli::set_opt

    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    $mysqli = new mysqli();
    $mysqli->set_opt(MYSQLI_OPT_READ_TIMEOUT, 3); // 3 seconds
    $mysqli->connect('example.com', 'user', 'pass', 'db');
    $mysqli->set_charset('utf8mb4'); // always set the charset
    

    或使用 INI 配置设置。在 php.ini 文件中设置:

    mysqlnd.net_read_timeout =  3
    

    如果没有通过mysqli::set_opt 提供,ini 设置只是MYSQLI_OPT_READ_TIMEOUT 的默认值,因此无论您选择哪种方式都可以。

    【讨论】:

    • 我在github上搜索了PHP的源码,发现MYSQLI_OPT_READ_TIMEOUT是从7.2版本开始添加的,如果在7.2版本之前使用这个常量,会报Notice错误
    • @ljfrocky 感谢您指出这一点。文档现已更新。
    猜你喜欢
    • 2013-10-17
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    相关资源
    最近更新 更多