Почему mysqli_connect не уважает MYSQLI_OPT_CONNECT_TIMEOUT?

#php #mysql #mysqli #timeout

#php #mysql #mysqli #тайм-аут

Вопрос:

Приведенный ниже код застрянет на real_connect() 100%. set_time_limit и default_socket_timeout и MYSQLI_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. Почему PHP-процесс зависает real_connect при использовании адреса хоста www.baidu.com и номера порта 80 ?
  2. Почему MYSQLI_OPT_CONNECT_TIMEOUT и другие настройки тайм-аута не работают?
  3. Для этой конкретной ситуации есть ли какой-либо способ установить время ожидания, которое может работать?

Комментарии:

1. Ну, mysql работает на порту 3306, а не на 80.

2. @AlexBarker Я это знаю. Я просто хочу знать, почему PHP застрял на real_connect при использовании адреса хоста «www.baidu.com » и номер порта «80», хотя я установил тайм-аут

3. Установите MYSQLI_OPT_READ_TIMEOUT также

Ответ №1:

Я нашел причину. Тайм-аут в моем случае — это тайм-аут чтения, а не тайм-аут соединения. Поэтому MYSQLI_OPT_CONNECT_TIMEOUT не работает. Решение состоит в том, чтобы установить mysqlnd.net_read_timeout в php.ini файле. Значение параметра указано в секундах.Например: 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
  

Параметр ini — это просто значение по умолчанию MYSQLI_OPT_READ_TIMEOUT , если оно не указано mysqli::set_opt , поэтому какой бы способ вы ни выбрали, он будет работать.

Комментарии:

1. Я искал исходный код PHP на github. Найдено, что MYSQLI_OPT_READ_TIMEOUT это было добавлено с версии 7.2. Если вы используете эту константу до версии 7.2, будет сообщено об ошибке уведомления

2. @ljfrocky Спасибо, что указали на это. Теперь документы обновлены.