PHP Conference Japan 2024

pg_connect_poll

(PHP 5 >= 5.6.0, PHP 7, PHP 8)

pg_connect_poll輪詢正在進行的非同步 PostgreSQL 連線嘗試的狀態

說明

pg_connect_poll(PgSql\Connection $connection): int

pg_connect_poll() 會輪詢透過使用 PGSQL_CONNECT_ASYNC 選項呼叫 pg_connect() 建立的 PostgreSQL 連線狀態。

參數

connection

一個 PgSql\Connection 實例。

更新日誌

版本 說明
8.1.0 connection 參數現在需要一個 PgSql\Connection 實例;先前需要的是一個 資源
新增註解

使用者貢獻的註解 1 則註解

VLroyrenn
5 年前
這個函式的文件說明相當簡略(很多 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");

// 第一次迭代時,也就是尚未呼叫 PQconnectPoll 時,行為如同上次返回 PGRES_POLLING_WRITING。
$poll_outcome = PGSQL_POLLING_WRITING;

while (
true) {
$socket = [pg_socket($conn)]; // 注意:不要假設 socket 在 PQconnectPoll 呼叫之間保持不變。
$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);
?>
To Top