因此,此函数的文档相当简陋(就像许多围绕 C 函数的 PHP 瘦包装器一样),但从我阅读 libpq 文档和尝试各种事物的经验来看,你可能应该了解以下内容:
* 当底层套接字繁忙时轮询连接会导致连接(或者至少是轮询,我不确定)失败。
* 正如 libpq 文档所述,“不要假设套接字在 PQconnectPoll 调用之间保持不变”。
* 连接状态发生任何变化后,套接字将变为就绪状态,因此必须多次轮询连接,直到该函数返回“polling_ok”或“polling_failed”。
* “polling_active”永远不会被 libpq 返回,而且实际上从未在任何地方使用过,它从一开始就是一个未使用的常量。
你需要做的是使用 pg_socket 获取与当前套接字相对应的 PHP 流对象,并在轮询之前等待它,如下所示:
<?php
function pg_wait_connection_ready($conn) {
assert(is_resource($conn));
assert(get_resource_type($conn) === "pgsql link" || get_resource_type($conn) === "pgsql link persistent");
$poll_outcome = PGSQL_POLLING_WRITING;
while (true) {
$socket = [pg_socket($conn)]; $null = [];
if ($poll_outcome === PGSQL_POLLING_READING) {
stream_select($socket, $null, $null, 5);
$poll_outcome = pg_connect_poll($conn);
} else if ($poll_outcome === PGSQL_POLLING_WRITING) {
stream_select($null, $socket, $null, 5);
$poll_outcome = pg_connect_poll($conn);
} else {
break;
}
}
}
$db = pg_connect($conn_string, PGSQL_CONNECT_ASYNC);
pg_wait_connection_ready($db);
pg_query($sql);
?>