PHP';当无法访问服务器时,s PDO将忽略MySQL的ATTR_TIMEOUT选项
我正在测试的场景中,mysql服务器无法通过输入随机IP来尝试连接。我使用PHP';当无法访问服务器时,s PDO将忽略MySQL的ATTR_TIMEOUT选项,php,mysql,pdo,connection,Php,Mysql,Pdo,Connection,我正在测试的场景中,mysql服务器无法通过输入随机IP来尝试连接。我使用PDO::ATTR_TIMEOUT=>1将PDO的选项设置为一秒钟后超时。但是,抛出异常仍然需要30秒。我猜这个超时只适用于实际的mysql连接时间,而不适用于运行mysql的服务器 我需要更改哪些PHP选项来暂停与mysql服务器的连接?在PHP.ini上,可以更新此配置变量: mysql.connect_timeout = 1 PDO::ATTR_TIMEOUT:以秒为单位指定超时持续时间不是全部 驱动程序支持此选项
PDO::ATTR_TIMEOUT=>1
将PDO的选项设置为一秒钟后超时。但是,抛出异常仍然需要30秒。我猜这个超时只适用于实际的mysql连接时间,而不适用于运行mysql的服务器
我需要更改哪些PHP选项来暂停与mysql服务器的连接?在
PHP.ini
上,可以更新此配置变量:
mysql.connect_timeout = 1
PDO::ATTR_TIMEOUT:以秒为单位指定超时持续时间不是全部
驱动程序支持此选项,其含义可能因驱动程序而异
驱动程序。例如,sqlite将在之前等待此时间值
放弃获取可写锁,但其他驱动程序可能会
将其解释为连接或读取超时间隔
文档明确指出,这可能并不意味着连接超时时间间隔,或者有时驱动程序不支持它
$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();
}
$host='192.168.1.36';
$dbname='test';
$username='test';
$password='';
$start=time();
试一试{
$db=新PDO(
“mysql:host=$host;dbname=$dbname”,
$username,
$password,
排列(
PDO::ATTR_TIMEOUT=>1,
PDO::ATTR_ERRMODE=>PDO::ERRMODE_异常
)
);
}捕获(例外$e){
回声时间()-$start;
回音“\n”;
echo$e->getMessage();
}
这个代码片段应该可以解决您的问题
mysqli、mysqlnd、pdo-mysql的区别:
- (已弃用)mysqlnd表示msyql本机驱动程序,其函数是过程性的
- mysql目录的mysqli对象形式
- pdo mysql是pdo数据库抽象插件,支持连接到mysql数据库
ini_set("default_socket_timeout", 2);
在PDO()连接字符串之前
(在Windows上测试,在Linux上也可以。)
为什么? 通过手册了解这一点: mysqlnd驱动程序对底层连接使用套接字,要设置超时,您需要使用套接字(流)超时函数。(参考号:) 使用mysqlnd意味着使用PHP流进行底层连接。对于mysqlnd,应该参考PHP流文档(streams),了解超时设置等详细信息,而不是MySQL客户机库的文档
如果您想要更多的控制,那么您可能能够更具体地控制实际的套接字:我没有测试过它,因为它只是unix。要设置mysqlnd使用的套接字,可以使用ini设置指定套接字(Ref:) 如果根据mysqlnd编译PDO_MYSQL,则可以通过PDO_MYSQL.default_socket设置设置默认套接字 看看那个场景 然后,您可以使用
但是设置默认值并在完成后重置可能更容易…将选项传递给PDO构造函数:
对我来说,如果你把这个选项放在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);
这不起作用。我将
ini\u设置为('mysql.connect\u timeout',1)代码>连接之前。几个问题-如何设置PDO::ATTR_TIMEOUT
,即连接字符串是什么?您是使用MySQLnd还是常规的mysql驱动程序?您的PHP和mysql驱动程序是什么版本的?您应该发布连接到mysql数据库所用的完整代码。启动赏金和不添加评论者请求的其他信息是没有意义的。@MatteoSp很抱歉,启动赏金后我变得非常忙。至于连接字符串,它几乎是nobody0day发布的内容。这是默认的Laravel连接器+超时,因此它使用异常作为错误模式。Linux上的MySQL驱动程序肯定不是这种情况-例如,如果您将PDO::ATTR\u timeout
设置为7,并且strace
脚本建立连接,您将看到connect(3,{sa\u family=AF\u INET,sin\u port=htons(3306),sin_addr=inet_addr(“10.0.0.0”)},16)=-1 EINPROGRESS(操作正在进行)轮询([{fd=3,events=POLLIN | POLLPRI}],1700
我使用的是mysqlnd,它应该支持它。您对本机驱动程序的评论非常错误。它非常不受欢迎。这个库提供了比原始mySQL驱动程序多得多的控制,应该使用它(例如,整数作为整数返回,而不是字符串,可以使用本机准备的语句)。旧的mySQL()函数被弃用:这根本没有连接到本机驱动程序。很有趣。如果我将默认\u socket\u timeout
设置为1秒,但不使用PDO连接超时选项,一秒钟后它不应该仍然超时吗?我只是问,因为我不确定发生了什么,但PDO超时突然开始为我工作,though同样的问题仍然存在于memcached连接中。这是正确的。Memcache在connect函数中有一个超时作为参数。因此,使用mysqlnd的默认套接字超时,memcachedPlease的参数在您的答案中包含实际的解决方案。链接不再工作,因为repo已以某种方式更改。