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

时间:2015-04-07 13:48:47

标签: php mysql pdo connection

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

我需要更改哪些PHP选项才能超时连接到mysql服务器?

6 个答案:

答案 0 :(得分:10)

刚刚放

ini_set("default_socket_timeout", 2);
在PDO()连接字符串之前

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

为什么?

通过手册追逐这个:

mysqlnd驱动程序使用套接字作为底层连接,并设置超时使用套接字(流)超时函数。 (参考:http://php.net/manual/en/mysqlnd.notes.php

  

使用mysqlnd意味着使用PHP流进行底层连接。对于mysqlnd,应该参考PHP流文档(Streams),例如超时设置,而不是MySQL客户端库的文档。

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

  

如果针对mysqlnd编译PDO_MYSQL,则可以通过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

设置超时

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

答案 1 :(得分:5)

php.ini上,您可以更新此配置变量:

mysql.connect_timeout = 1

答案 2 :(得分:3)

答案 3 :(得分:1)

  

PDO :: ATTR_TIMEOUT:指定超时持续时间(以秒为单位)。 不是全部   drivers支持此选项,其含义可能因驱动程序而异   驱动器即可。例如,sqlite之前会等待这个时间值   放弃获得可写锁,但其他司机可能   将其解释为连接或读取超时间隔。

该文件明确指出,它可能并不意味着连接超时间隔或有时驱动程序不支持它。

答案 4 :(得分:1)


    $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本机驱动程序,其功能是程序性的
  • mysq目录形式的mysql diriver
  • pdo-mysql是pdo数据库抽象的插件,支持连接到mysql数据库。

答案 5 :(得分:0)

对我来说,如果将选项放在PDO的构造函数中,它将起作用。并忽略php.ini中的任何设置。

$options = array(PDO::ATTR_TIMEOUT] => 1);//must be in the constructor
$db = new DB($dsn, $username, $password, $options);

由于在这里我们正在测试初始连接,因此在打开连接时需要具有此选项才有意义。因此,在初始连接后,以下任何查询都可以使用。

$db = new DB($dsn, $username, $password, $options);
$db->setAttribute(PDO::ATTR_TIMEOUT, 2);