因此,此函数的文档非常简陋(许多围绕 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);
?>