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() 轮询通过调用 pg_connect() 并使用 PGSQL_CONNECT_ASYNC 选项创建的 PostgreSQL 连接的状态。

参数

connection

一个 PgSql\Connection 实例。

变更日志

版本 描述
8.1.0 connection 参数现在期望一个 PgSql\Connection 实例;以前,期望一个 资源
添加注释

用户贡献注释 1 个注释

3
VLroyrenn
5 年前
因此,此函数的文档非常简陋(许多围绕 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");

// “在第一次迭代中,即如果您尚未调用 PQconnectPoll,则表现得好像它上次返回 PGRES_POLLING_WRITING。”
$poll_outcome = PGSQL_POLLING_WRITING;

while (
true) {
$socket = [pg_socket($conn)]; // “注意:不要假设套接字在 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