Pg flush: примеры (PHP)

Использование pg_flush для асинхронных запросов к базе данных
Раздел: Базы данных (PostgreSQL)
pg_flush(PgSql\Connection $connection): int|bool

Описание функции pg_flush

Функция pg_flush выполняет сброс буферизованных выходных данных в неблокирующем соединении с сервером PostgreSQL. Она актуальна при работе с асинхронными запросами, когда необходимо принудительно отправить накопленные в буфере данные на сервер без блокировки выполнения скрипта.

Аргументы функции

Функция принимает один обязательный параметр:

  • $connection (ресурс) - идентификатор соединения с базой данных PostgreSQL, полученный через pg_connect().
Возвращаемые значения
  • true - все буферизованные данные успешно отправлены на сервер.
  • 0 - данные остались в буфере, требуется повторный вызов функции.
  • false - произошла ошибка (например, неверный идентификатор соединения).

Примеры использования pg_flush

Базовое применение с неблокирующим соединением
<?php
$conn = pg_connect('host=localhost dbname=test user=postgres', PGSQL_CONNECT_ASYNC);
$result = pg_query($conn, 'SELECT 1');

while (true) {
    $flushResult = pg_flush($conn);
    if ($flushResult === true) {
        echo 'Данные отправлены';
        break;
    } elseif ($flushResult === 0) {
        echo 'Ожидание отправки...';
        usleep(1000);
    } else {
        echo 'Ошибка отправки';
        break;
    }
}
?>
Ожидание отправки...
Ожидание отправки...
Данные отправлены

Похожие функции в PHP

Отправляет асинхронный запрос без ожидания результата. Часто используется вместе с pg_flush для контроля отправки данных. Предпочтительнее для инициирования асинхронных операций.

Проверяет, занято ли соединение выполнением запроса. Полезно в комбинации с pg_flush для мониторинга состояния.

Получает результат асинхронного запроса. Используется после успешного сброса буфера через pg_flush.

Аналоги в других языках

Python (asyncpg)
import asyncpg
import asyncio

async def example():
    conn = await asyncpg.connect('postgresql://user:pass@localhost/db')
    # Неявный сброс буфера при выполнении запроса
    await conn.execute('SELECT 1')
    # Явное управление отсутствует

asyncio.run(example())
JavaScript (node-postgres)
const { Client } = require('pg');
const client = new Client();
await client.connect();
// Буферизация управляется автоматически
const res = await client.query('SELECT $1::text', ['test']);
MySQL (C API)

Функция mysql_send_query в C API MySQL аналогична по концепции, но в PHP расширении mysqli отсутствует прямое соответствие.

Типичные ошибки

Использование с блокирующим соединением
<?php
$conn = pg_connect('host=localhost'); // По умолчанию блокирующее
$flush = pg_flush($conn); // Возвращает false
var_dump($flush);
?>
bool(false)
Попытка сброса после закрытия соединения
<?php
$conn = pg_connect('host=localhost', PGSQL_CONNECT_ASYNC);
pg_close($conn);
echo pg_flush($conn) ? 'Успех' : 'Ошибка';
?>
Warning: pg_flush(): supplied resource is not a valid PostgreSQL link resource
Ошибка

Изменения в версиях PHP

PHP 8.1.0

Функция начала возвращать 0 вместо true при частичной отправке буферизованных данных. Ранее в этой ситуации могло возвращаться true.

PHP 8.0.0

Параметр $connection теперь ожидает экземпляр PgSql\Connection вместо ресурса. Функция вызывает ошибку типа TypeError при неверном аргументе.

Расширенные примеры

Контроль буферизации больших запросов
Пример php
<?php
$conn = pg_connect('host=localhost', PGSQL_CONNECT_ASYNC);
pg_send_query($conn, 'INSERT INTO large_data VALUES (' . str_repeat('x', 100000) . ')');

$attempts = 0;
while (($status = pg_connection_busy($conn)) !== false) {
    $flushResult = pg_flush($conn);
    if ($flushResult === 0) {
        $attempts++;
        echo 'Попытка ' . $attempts . ': данные буферизованы<br>';
    } elseif ($flushResult === true) {
        echo 'Запрос полностью отправлен за ' . $attempts . ' попыток';
        break;
    }
    usleep(50000);
}
?>
Попытка 1: данные буферизованы
Попытка 2: данные буферизованы
Запрос полностью отправлен за 3 попыток
Интеграция с многозадачностью
Пример php
<?php
function async_flush($connections) {
    $active = $connections;
    while (!empty($active)) {
        foreach ($active as $key => $conn) {
            $result = pg_flush($conn);
            if ($result === true) {
                echo 'Соединение ' . $key . ' готово<br>';
                unset($active[$key]);
            } elseif ($result === false) {
                echo 'Ошибка в соединении ' . $key . '<br>';
                unset($active[$key]);
            }
        }
        usleep(1000);
    }
}

$conn1 = pg_connect('host=db1', PGSQL_CONNECT_ASYNC);
$conn2 = pg_connect('host=db2', PGSQL_CONNECT_ASYNC);
pg_send_query($conn1, 'SELECT pg_sleep(0.01)');
pg_send_query($conn2, 'SELECT 1');
async_flush(['db1' => $conn1, 'db2' => $conn2]);
?>
Соединение db2 готово
Соединение db1 готово

PHP pg_flush function comments

En
Pg flush Flush outbound query data on the connection