PHP PDO игнорирует параметр ATTR_TIMEOUT для MySQL, когда сервер не может быть достигнут
Я тестирую сценарии, в которых сервер mysql не может быть достигнут, помещая случайный IP-адрес, чтобы попытаться подключиться. Я установил опции PDO на тайм-аут через одну секунду, используя PDO::ATTR_TIMEOUT => 1
. Однако для исключения исключений требуется еще 30 секунд. Я предполагаю, что этот тайм-аут применим только к фактическому времени соединения mysql, а не к серверу, на котором работает mysql.
Какие параметры PHP мне нужно изменить, чтобы отключить соединение с сервером mysql?
Ответы
Ответ 1
Просто поместите
ini_set("default_socket_timeout", 2);
перед вашей связью PDO().
(Протестировано в Windows, также должно быть хорошо в Linux.)
Почему?
Преследуя это через руководство:
Драйвер mysqlnd использует сокеты для базового соединения, а для установки тайм-аутов вам нужно использовать функции тайм-аута сокета (потока). (Ссылка: http://php.net/manual/en/mysqlnd.notes.php)
Использование mysqlnd означает использование потоков PHP для базового подключения. Для mysqlnd в документации по потокам PHP (потоки) следует обращаться по таким деталям, как настройки тайм-аута, а не к документации для клиентской библиотеки MySQL.
Если вы хотите большего контроля, тогда вы сможете более точно управлять фактическим сокетом: я не тестировал это, поскольку он только unix. Чтобы установить сокет mysqlnd, вы можете указать сокет, используя ini-настройки (Ref: http://php.net/manual/en/ref.pdo-mysql.connection.php)
Если PDO_MYSQL скомпилирован против mysqlnd, по умолчанию можно установить сокет по умолчанию через параметр pdo_mysql.default_socket.
См. http://php.net/manual/en/ref.pdo-mysql.php#ini.pdo-mysql.default-socket об этом параметре
Возможно, вы сможете установить таймаут, используя http://php.net/manual/en/function.stream-set-timeout.php
Но, возможно, проще установить значение по умолчанию, а затем reset как только вы закончите...
Ответ 2
В php.ini
вы можете обновить эту конфигурационную переменную:
mysql.connect_timeout = 1
Ответ 3
Передайте параметры конструктору PDO:
https://github.com/phalcon/cphalcon/blob/2.0.0/phalcon/db/adapter/pdo.zep#L135-L149
Ответ 4
PDO:: ATTR_TIMEOUT: указывает продолжительность таймаута в секундах. Не все драйверы поддерживают этот параметр, и его значение может отличаться от драйвера к водитель. Например, sqlite будет ожидать до этого значения времени до отказавшись от получения записываемого замка, но другие драйверы могут интерпретировать это как интервал времени подключения или таймаута чтения.
В документе четко указано, что это может не означать интервал тайм-аута соединения, или иногда драйвер не поддерживает его.
Ответ 5
$host = '192.168.1.36';
$dbname = 'test';
$username = 'test';
$password = '';
$start = time();
try {
$db = new PDO(
"mysql:host=$host;dbname=$dbname",
$username,
$password,
array(
PDO::ATTR_TIMEOUT => 1,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
)
);
} catch(Exception $e) {
echo time() - $start;
echo "\n";
echo $e->getMessage();
}
Этот фрагмент кода должен решить вашу проблему.
разница mysqli, mysqlnd, pdo-mysql:
- (устаревший) mysqlnd означает собственный драйвер msyql, функции которого процедурные
- mysqli объектная форма mysql diriver
- pdo-mysql - это плагин для абстракции базы данных pdo для поддержки подключения к базе данных mysql.