Pg last notice: примеры (PHP)

Получение уведомлений PostgreSQL через pg_last_notice
Раздел: Базы данных (PostgreSQL)
pg_last_notice(PgSql\Connection $connection, int $mode = PGSQL_NOTICE_LAST): array|string|bool

Функция pg_last_notice в PHP

Описание и назначение

Функция pg_last_notice возвращает последнее уведомление (notice), сгенерированное сервером PostgreSQL для указанного соединения. Уведомления отличаются от ошибок и обычно носят информационный характер, например, предупреждения о неявных приведениях типов или устаревших конструкциях.

Когда применяется

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

Аргументы функции
  • $connection (обязательный, ресурс или объект PgSql\Connection) – соединение с базой данных PostgreSQL, полученное через pg_connect. В PHP 8+ ожидается объект.
  • $option (опциональный, int) – флаг для управления форматом вывода. Поддерживается с PHP 8.1.
    • PGSQL_NOTICE_LAST – возвращает только последнее уведомление (по умолчанию).
    • PGSQL_NOTICE_ALL – возвращает все уведомления в виде массива.

Примеры применения pg_last_notice

Базовый пример с уведомлением

Создание таблицы с существующим именем и вывод уведомления.

<?php
$conn = pg_connect("host=localhost dbname=test user=postgres");
$query = "CREATE TABLE test_table (id SERIAL PRIMARY KEY)";
pg_query($conn, $query);
// Повторное создание таблицы вызовет уведомление
$query2 = "CREATE TABLE IF NOT EXISTS test_table (id SERIAL)";
pg_query($conn, $query2);
$notice = pg_last_notice($conn);
echo "Уведомление: $notice";
?>
Уведомление: NOTICE:  отношение "test_table" уже существует, пропускаем
Использование флага PGSQL_NOTICE_ALL
<?php
$conn = pg_connect("host=localhost dbname=test");
// Включение расширенного вывода уведомлений
pg_query($conn, "SET client_min_messages TO NOTICE");
// Генерация нескольких уведомлений
pg_query($conn, "CREATE TEMP TABLE tmp1 (id int)");
pg_query($conn, "CREATE TEMP TABLE IF NOT EXISTS tmp1 (id int)");
pg_query($conn, "CREATE TEMP TABLE IF NOT EXISTS tmp1 (id int)");
$notices = pg_last_notice($conn, PGSQL_NOTICE_ALL);
print_r($notices);
?>
Array
(
    [0] => NOTICE:  CREATE TABLE будет создавать неявную последовательность для столбца "tmp1.id"
    [1] => NOTICE:  отношение "tmp1" уже существует, пропускаем
    [2] => NOTICE:  отношение "tmp1" уже существует, пропускаем
)

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

pg_result_error

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

pg_last_error

Возвращает последнее сообщение об ошибке для соединения. Применяется для диагностики критических сбоев, а не для уведомлений.

Когда что выбирать

Функция pg_last_notice предназначена для информационных сообщений. Для обработки ошибок используются pg_last_error и pg_result_error. В PHP 8+ рекомендуется использовать объектно-ориентированное расширение PDO с драйвером pgsql, которое предоставляет механизм исключений и ошибок через PDO::errorInfo.

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

Python (psycopg2)

Используется атрибут connection.notices, содержащий список уведомлений.

import psycopg2
conn = psycopg2.connect("dbname=test")
cur = conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS test (id SERIAL)")
cur.execute("CREATE TABLE IF NOT EXISTS test (id SERIAL)")
print(conn.notices)
['NOTICE:  отношение "test" уже существует, пропускаем\n']
JavaScript (node-postgres)

Событие notice на объекте клиента.

const { Client } = require('pg');
const client = new Client();
client.connect();
client.on('notice', (msg) => {
  console.log('Notice:', msg);
});
await client.query('CREATE TABLE IF NOT EXISTS test (id SERIAL)');
MySQL

Аналогов прямых уведомлений нет. Информационные сообщения возвращаются как результат запроса SHOW WARNINGS.

CREATE TABLE IF NOT EXISTS test (id INT);
SHOW WARNINGS;

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

Неверный тип соединения
<?php
// Передача несуществующего соединения
$notice = pg_last_notice(null);
var_dump($notice);
?>
Warning: pg_last_notice(): supplied resource is not a valid PostgreSQL link resource
Игнорирование необходимости настройки клиента

По умолчанию PostgreSQL может не возвращать все уведомления. Требуется настройка уровня сообщений.

<?php
$conn = pg_connect("host=localhost");
// Без настройки уведомления могут не возвращаться
pg_query($conn, "CREATE TABLE IF NOT EXISTS test (id SERIAL)");
$notice = pg_last_notice($conn);
var_dump($notice); // Может быть false
?>

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

PHP 8.1

Добавлен необязательный второй аргумент $option для управления форматом возвращаемых данных. Параметр позволяет получать все уведомления в виде массива через константу PGSQL_NOTICE_ALL.

PHP 8.0

Изменен тип ожидаемого аргумента: вместо ресурса теперь требуется объект PgSql\Connection. Вызов функции с ресурсом вызовет предупреждение.

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

Мониторинг уведомлений в цикле
Пример php
<?php
$conn = pg_connect("host=localhost");
pg_query($conn, "SET client_min_messages TO NOTICE");
$queries = [
    "CREATE TEMP TABLE t (id SERIAL)",
    "ALTER TABLE t ADD COLUMN name text",
    "ALTER TABLE t ADD COLUMN name text"
];
foreach ($queries as $query) {
    pg_query($conn, $query);
    $notice = pg_last_notice($conn);
    if ($notice) {
        echo "[$query] => $notice\n";
    }
}
?>
[ALTER TABLE t ADD COLUMN name text] => NOTICE:  столбец "name" отношения "t" уже существует
Логирование уведомлений в файл
Пример php
<?php
$conn = pg_connect("host=localhost");
pg_query($conn, "SET client_min_messages TO NOTICE");
function log_notices($connection, $log_file) {
    $notices = pg_last_notice($connection, PGSQL_NOTICE_ALL);
    if ($notices) {
        file_put_contents($log_file, implode("\n", $notices), FILE_APPEND);
    }
}
pg_query($conn, "CREATE TABLE IF NOT EXISTS users (id SERIAL)");
log_notices($conn, 'notices.log');
?>
Обработка уведомлений о deprecated-функциях
Пример php
<?php
$conn = pg_connect("host=localhost");
pg_query($conn, "SET client_min_messages TO NOTICE");
// Использование устаревшего типа данных
pg_query($conn, "CREATE TABLE old (price money)");
$notice = pg_last_notice($conn);
if (preg_match('/deprecated/i', $notice)) {
    echo "Обнаружено устаревшее использование: $notice";
}
?>

PHP pg_last_notice function comments

En
Pg last notice Returns the last notice message from PostgreSQL server