Pg send query: примеры (PHP)

Асинхронные запросы PostgreSQL через pg_send_query
Раздел: Базы данных (PostgreSQL)
pg_send_query(PgSql\Connection $connection, string $query): int|bool
Основные сведения о функции

Функция pg_send_query предназначена для асинхронной отправки SQL-запроса или нескольких запросов на выполнение через соединение с базой данных PostgreSQL.

Применение функции актуально в ситуациях, когда необходимо отправить запрос без ожидания его завершения, что позволяет продолжить выполнение скрипта. Это может быть полезно для отправки неблокирующих запросов или выполнения нескольких операций параллельно.

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

  • connection — ресурс соединения с PostgreSQL.
  • query — строка, содержащая один или несколько SQL-запросов, разделенных точкой с запятой.

Возвращаемое значение: в случае успешной отправки возвращает true, при ошибке — false.

Базовые примеры использования
Отправка одиночного запроса
<?php
$connection = pg_connect("host=localhost dbname=test user=postgres");
if ($connection) {
    $result = pg_send_query($connection, "SELECT * FROM users WHERE id = 1");
    if ($result) {
        echo "Запрос отправлен";
    } else {
        echo "Ошибка отправки";
    }
}
?>
Запрос отправлен
Отправка нескольких запросов
<?php
$connection = pg_connect("host=localhost dbname=test");
$queries = "INSERT INTO logs (message) VALUES ('test1'); INSERT INTO logs (message) VALUES ('test2');";
$sendResult = pg_send_query($connection, $queries);
var_dump($sendResult);
?>
bool(true)
Похожие функции в PHP

pg_query — синхронное выполнение запроса. Ожидает завершения и сразу возвращает результат. Подходит для большинства стандартных операций.

pg_send_query_params — асинхронная отправка параметризованного запроса. Рекомендуется для запросов с пользовательскими данными из-за безопасности.

pg_send_prepare и pg_send_execute — асинхронная работа с подготовленными запросами. Полезны при многократном выполнении схожих запросов.

Выбор зависит от необходимости асинхронности и типа запроса. Для простых запросов без параметров используют pg_send_query, для данных извне — pg_send_query_params.

Аналоги в других языках
Python (библиотека asyncpg)
import asyncio
import asyncpg

async def async_query():
    conn = await asyncpg.connect('postgresql://user:pass@localhost/db')
    await conn.execute('INSERT INTO logs(message) VALUES($1)', 'test')
    await conn.close()

asyncio.run(async_query())
JavaScript (библиотека pg)
const { Client } = require('pg');
const client = new Client();
await client.connect();
const res = await client.query('SELECT $1::text as message', ['Hello']);
console.log(res.rows[0].message);
await client.end();
MySQL (нативный асинхронный драйвер)

В MySQL асинхронные запросы обычно реализуются через неблокирующие соединения в драйверах, таких как mysql2 для Node.js или asyncio для Python.

Основное отличие от PHP: в Python и JavaScript асинхронность встроена в язык, что упрощает написание неблокирующего кода.

Типичные ошибки
Отсутствие проверки соединения
<?php
$connection = false;
$result = pg_send_query($connection, "SELECT 1");
var_dump($result);
?>
bool(false)

Функция возвращает false при неверном соединении.

Ожидание результата без использования pg_get_result
<?php
$conn = pg_connect("host=localhost dbname=test");
pg_send_query($conn, "SELECT 1");
// Попытка сразу использовать pg_fetch_result приведет к ошибке
$row = pg_fetch_result(pg_get_result($conn), 0, 0);
echo $row;
?>
1

Для получения результата асинхронного запроса требуется сначала вызвать pg_get_result.

История изменений

В PHP 8.1.0 изменений в поведении функции не было. В PHP 8.0.0 функция стала строже к типам аргументов, ожидается ресурс соединения.

Начиная с PHP 7.4.0, функция корректно обрабатывает ошибки при передаче неверного типа аргументов.

Рекомендуется использовать последние версии PHP для улучшенной обработки ошибок и стабильности.

Расширенные примеры
Параллельная отправка нескольких запросов
Пример php
<?php
$conn = pg_connect("host=localhost dbname=test");
$query1 = "SELECT pg_sleep(2), 'slow query' as result";
$query2 = "SELECT 'fast query' as result";

pg_send_query($conn, $query1);
pg_send_query($conn, $query2); // Отправляется до завершения первого

// Получение результатов
$res1 = pg_get_result($conn);
$res2 = pg_get_result($conn);

echo pg_fetch_result($res2, 0, 0); // fast query
// Далее можно получить результат первого запроса
?>
fast query
Обработка ошибок в асинхронных запросах
Пример php
<?php
$conn = pg_connect("host=localhost dbname=test");
pg_send_query($conn, "SELECT * FROM non_existing_table");
$result = pg_get_result($conn);
if (pg_result_error($result)) {
    echo "Ошибка запроса: ". pg_result_error($result);
}
?>
Ошибка запроса: ERROR: relation "non_existing_table" does not exist
Комбинирование с pg_connection_busy
Пример php
<?php
$conn = pg_connect("host=localhost dbname=test");
pg_send_query($conn, "SELECT pg_sleep(1)");
while (pg_connection_busy($conn)) {
    echo "Соединение занято, ожидание...\n";
    usleep(100000);
}
$result = pg_get_result($conn);
echo "Запрос завершен\n";
?>
Соединение занято, ожидание...
Запрос завершен

PHP pg_send_query function comments

En
Pg send query Sends asynchronous query