Signatur
Beschreibung
pg_get_notify() prüft die interne Nachrichtenwarteschlange der PostgreSQL-Verbindung auf eingehende NOTIFY-Ereignisse. Solche Ereignisse werden von anderen PostgreSQL-Prozessen oder Sessions ausgelöst, wenn diese das SQL-Kommando NOTIFY kanalname ausführen. Die Funktion ermöglicht so eine asynchrone, einfache Prozesskommunikation über die Datenbank, ohne permanentes Polling auf Tabellen durchführen zu müssen.
Um Benachrichtigungen für einen bestimmten Kanal zu empfangen, muss die eigene Session zuvor mit dem SQL-Befehl LISTEN kanalname auf diesem Kanal registriert sein. pg_get_notify() gibt genau eine Nachricht pro Aufruf zurück; bei mehreren wartenden Nachrichten muss die Funktion wiederholt aufgerufen werden, bis sie false zurückgibt.
Der optionale Parameter $result_type steuert das Format des zurückgegebenen Arrays: PGSQL_ASSOC (Standard) liefert ein assoziatives Array mit den Schlüsseln message, pid und (ab PostgreSQL 9.0) payload; PGSQL_NUM liefert ein numerisch indiziertes Array; PGSQL_BOTH liefert beides kombiniert.
Typische Einsatzszenarien sind Echtzeit-Benachrichtigungen bei Datenänderungen, Cache-Invalidierungen oder die Koordination von Worker-Prozessen, ohne dass eine zusätzliche Message-Queue-Infrastruktur benötigt wird.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $connection Pflicht | PgSql\Connection | Eine aktive PostgreSQL-Verbindungsinstanz, die zuvor mit pg_connect() oder pg_pconnect() erzeugt wurde. |
|
| $result_type | int | PGSQL_ASSOC | Bestimmt das Format des zurückgegebenen Arrays. Erlaubte Werte: PGSQL_ASSOC (assoziativ), PGSQL_NUM (numerisch) oder PGSQL_BOTH (beides). |
Rückgabewert
message (Kanalname), pid (Prozess-ID des sendenden Prozesses) und payload (optionale Nutzlast, ab PostgreSQL 9.0) zurück, wenn eine Nachricht vorliegt. Gibt false zurück, wenn keine Benachrichtigung in der Warteschlange vorhanden ist oder ein Fehler auftritt.Beispiele
Einfaches LISTEN/NOTIFY-Beispiel
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=secret');
if (!$conn) {
die('Verbindung fehlgeschlagen');
}
// Kanal abonnieren
pg_query($conn, "LISTEN mein_kanal");
echo "Warte auf NOTIFY-Nachrichten auf Kanal 'mein_kanal'..." . PHP_EOL;
// Polling-Schleife (in der Praxis mit sleep() oder stream_select() ergänzen)
for ($i = 0; $i < 10; $i++) {
// Verbindung aktualisieren, damit neue Benachrichtigungen ankommen
pg_query($conn, "SELECT 1");
$notify = pg_get_notify($conn, PGSQL_ASSOC);
if ($notify !== false) {
echo "Kanal: " . $notify['message'] . PHP_EOL;
echo "PID: " . $notify['pid'] . PHP_EOL;
if (isset($notify['payload'])) {
echo "Payload: " . $notify['payload'] . PHP_EOL;
}
break;
}
sleep(1);
}
pg_close($conn);
Alle ausstehenden Nachrichten leeren
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=secret');
pg_query($conn, "LISTEN updates");
pg_query($conn, "LISTEN alerts");
// Neue Nachrichten durch SELECT auffrischen
pg_query($conn, "SELECT 1");
// Alle wartenden Nachrichten der Reihe nach abholen
$nachrichten = [];
while (($notify = pg_get_notify($conn)) !== false) {
$nachrichten[] = $notify;
}
if (empty($nachrichten)) {
echo "Keine ausstehenden Benachrichtigungen." . PHP_EOL;
} else {
foreach ($nachrichten as $n) {
printf("[%s] von PID %d: %s\n", $n['message'], $n['pid'], $n['payload'] ?? '(kein Payload)');
}
}
pg_close($conn);
// Wichtig · Fallstricke
Wichtig: pg_get_notify() liest nur Nachrichten, die seit dem letzten Austausch mit dem Server eingegangen sind. Damit neue Benachrichtigungen erkannt werden, muss zuvor eine Abfrage an die Datenbank gesendet werden (z. B. pg_query($conn, "SELECT 1")), oder es muss ein nicht-blockierender Socket-Ansatz mit pg_socket() und stream_select() verwendet werden.
Ab PostgreSQL 9.0 können NOTIFY-Kommandos eine optionale Nutzlast (Payload) bis zu 8000 Zeichen übermitteln: NOTIFY kanalname, 'meine Nutzlast'. Ältere PostgreSQL-Versionen unterstützen diesen Payload-Parameter nicht.
Der Kanal-Name bei LISTEN/NOTIFY wird in PostgreSQL wie ein Bezeichner behandelt und ist standardmäßig case-insensitiv (Kleinbuchstaben). Anführungszeichen erzwingen Case-Sensitivity.