Подтвердить что ты не робот

PHP PDO игнорирует параметр ATTR_TIMEOUT для MySQL, когда сервер не может быть достигнут

Я тестирую сценарии, в которых сервер mysql не может быть достигнут, помещая случайный IP-адрес, чтобы попытаться подключиться. Я установил опции PDO на тайм-аут через одну секунду, используя PDO::ATTR_TIMEOUT => 1. Однако для исключения исключений требуется еще 30 секунд. Я предполагаю, что этот тайм-аут применим только к фактическому времени соединения mysql, а не к серверу, на котором работает mysql.

Какие параметры PHP мне нужно изменить, чтобы отключить соединение с сервером mysql?

4b9b3361

Ответ 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

Ответ 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.