這個函式的文件說明相當簡略(很多 PHP 對 C 函式的輕量封裝都是這樣),但根據我閱讀 libpq 文件和嘗試各種方法所收集到的資訊,您可能需要知道以下幾點
* 在底層 socket 忙碌時輪詢連線會導致連線(或至少是輪詢,我不確定)失敗。
* 正如 libpq 文件所述,「不要假設 socket 在 PQconnectPoll 呼叫之間保持不變」
* socket 在連線狀態每次變化後都會變成就緒狀態,因此必須多次輪詢連線,直到函式返回「polling_ok」或「polling_failed」。
* libpq 永遠不會返回「polling_active」,而且從未在任何地方使用過,它從第一天起就是一個未使用的常數。
您需要做的是使用 pg_socket 取得對應於目前 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);
?>