无法轮询/等待通知到来。你必须进入繁忙循环或休眠。这两种方法都很糟糕。如果 PHP 可以访问 PQsocket,以便可以在套接字连接上使用 select(),那就太好了。这就是从 C 或 Perl 中如何实现的。
(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)
pg_get_result — 获取异步查询结果
pg_get_result() 从 pg_send_query(),pg_send_query_params() 或 pg_send_execute() 执行的异步查询中获取 PgSql\Result 实例。
pg_send_query() 和其他异步查询函数可以向 PostgreSQL 服务器发送多个查询,而 pg_get_result() 用于逐一获取每个查询的结果。
一个 PgSql\Result 实例,如果不再有结果可用则返回 false
。
版本 | 描述 |
---|---|
8.1.0 | 现在返回一个 PgSql\Result 实例;以前返回的是一个 资源。 |
8.1.0 | connection 参数现在需要一个 PgSql\Connection 实例;以前需要的是一个 资源。 |
示例 #1 pg_get_result() 示例
<?php
$dbconn = pg_connect("dbname=publisher") or die("无法连接");
if (!pg_connection_busy($dbconn)) {
pg_send_query($dbconn, "select * from authors; select count(*) from authors;");
}
$res1 = pg_get_result($dbconn);
echo "第一次调用 pg_get_result(): $res1\n";
$rows1 = pg_num_rows($res1);
echo "$res1 包含 $rows1 条记录\n\n";
$res2 = pg_get_result($dbconn);
echo "第二次调用 pg_get_result(): $res2\n";
$rows2 = pg_num_rows($res2);
echo "$res2 包含 $rows2 条记录\n";
?>
以上示例将输出
First call to pg_get_result(): Resource id #3 Resource id #3 has 3 records Second call to pg_get_result(): Resource id #4 Resource id #4 has 1 records
无法轮询/等待通知到来。你必须进入繁忙循环或休眠。这两种方法都很糟糕。如果 PHP 可以访问 PQsocket,以便可以在套接字连接上使用 select(),那就太好了。这就是从 C 或 Perl 中如何实现的。
在发送单个查询后调用 pg_get_result() 之后,连接似乎不会处于繁忙状态。然而,正确的方法是在循环中额外调用 pg_get_result(),直到它返回 false [1]。
<?php
$conn = pg_connect('...', PGSQL_CONNECT_FORCE_NEW);
for ($i = 0; $i < 10000; $i++) {
$query = '错误的查询';
if (pg_connection_busy($conn)) {
fprintf(STDERR, "连接繁忙\n");
exit(1);
}
pg_send_query($conn, $query);
$res = pg_get_result($conn);
if ($res === false) {
fprintf(STDERR, "预期结果\n");
exit(1);
}
/*对于正确的查询,以下步骤似乎没有必要,但对于错误的查询至关重要。
注释掉循环会导致此脚本因“连接繁忙”错误而失败。*/
while (pg_get_result($conn));
// 结果处理...
}
?>
详情请参见 https://postgresql.ac.cn/message-id/flat/[email protected]#[email protected] 和 https://bugs.php.net/bug.php?id=52750。
[1] 或者更好的是,从 PHP 5.6 开始使用异步连接。
要使用异步查询获得简单的等待输出,可以使用 pg_connection_busy 命令
<?php
$dbh = pg_connect("host=XXX user=XXX password=XXX dbname=XXX");
if (!$dbh)
{
print "连接失败";
exit;
}
$query = "SELECT pg_sleep(10)";
if (!pg_connection_busy($dbh))
{
$sent = pg_send_query($dbh, $query);
print "已发送查询,等待:";
while (pg_connection_busy($dbh)
{
print ".";
flush();
}
$res = pg_get_result($dbh);
print "<br>"; // 或 \n
print "结果是:$res";
}
pg_close($dbh);
?>
william at 25thandClement dot com 说:“无法轮询/等待通知到来……”
可以。如果正在进行查询,pg_get_result() 将阻塞并返回该查询完成后结果。