Signatur
Beschreibung
pg_socket() liefert ein Socket-Handle für die angegebene PostgreSQL-Verbindung. Das zurückgegebene Handle ist ein Nur-Lese-Handle – es darf also nicht zum Schreiben verwendet werden. Der primäre Anwendungsfall ist die Kombination mit stream_select() oder ähnlichen Stream-Funktionen, um nicht-blockierendes, asynchrones Warten auf PostgreSQL-Ergebnisse zu implementieren.
Dies ist besonders nützlich in Kombination mit pg_send_query(), pg_send_execute() oder pg_send_query_params(): Man schickt eine Abfrage asynchron ab und wartet dann mit stream_select() auf das Socket, bis Daten verfügbar sind – anstatt den Prozess mit pg_get_result() blockierend zu blockieren.
Das zurückgegebene Handle ist vom Typ Socket (seit PHP 8.0, davor eine Ressource). Es darf nicht geschlossen werden, da es zur internen PostgreSQL-Verbindungsressource gehört. Das Schließen würde die Verbindung beschädigen.
Typische Einsatzszenarien sind Event-Loop-Architekturen oder Server-seitige PHP-Prozesse, die mehrere Datenbankverbindungen gleichzeitig überwachen müssen, ohne für jede einzeln blockieren zu wollen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $connection Pflicht | PgSql\Connection | Eine aktive PostgreSQL-Verbindungsinstanz, die zuvor mit pg_connect() oder pg_pconnect() erstellt wurde. |
Rückgabewert
false zurückgegeben. Das Handle darf nur lesend mit stream_select() o. Ä. verwendet werden, nicht zum Schreiben und nicht geschlossen werden.Beispiele
Asynchrone Abfrage mit stream_select() und pg_socket()
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=secret');
if (!$conn) {
die('Verbindung fehlgeschlagen');
}
// Asynchrone Abfrage senden
if (!pg_send_query($conn, 'SELECT pg_sleep(1), 42 AS answer')) {
die('Abfrage konnte nicht gesendet werden');
}
// Socket-Handle holen
$socket = pg_socket($conn);
if ($socket === false) {
die('Socket konnte nicht ermittelt werden');
}
// Warten, bis Daten verfügbar sind (max. 5 Sekunden)
$read = [$socket];
$write = null;
$except = null;
while (true) {
$ready = stream_select($read, $write, $except, 5);
if ($ready === false) {
die('stream_select() Fehler');
}
if ($ready > 0) {
// Verbindungsstatus aktualisieren
pg_consume_input($conn);
if (!pg_connection_busy($conn)) {
break; // Ergebnis bereit
}
}
$read = [$socket]; // stream_select() leert das Array – zurücksetzen
}
$result = pg_get_result($conn);
if ($result) {
$row = pg_fetch_assoc($result);
echo 'Antwort: ' . $row['answer'] . PHP_EOL;
}
pg_close($conn);
Mehrere PostgreSQL-Verbindungen gleichzeitig überwachen
<?php
$dsn = 'host=localhost dbname=testdb user=postgres password=secret';
$conn1 = pg_connect($dsn . ' connect_timeout=5');
$conn2 = pg_connect($dsn . ' connect_timeout=5 options=\'--application_name=conn2\'');
pg_send_query($conn1, 'SELECT 1 AS id');
pg_send_query($conn2, 'SELECT 2 AS id');
$sockets = [
pg_socket($conn1),
pg_socket($conn2),
];
$connections = [$conn1, $conn2];
$read = $sockets;
$write = null;
$except = null;
$done = 0;
while ($done < 2) {
$ready = stream_select($read, $write, $except, 5);
if ($ready > 0) {
foreach ($connections as $i => $conn) {
pg_consume_input($conn);
if (!pg_connection_busy($conn)) {
$result = pg_get_result($conn);
if ($result && !isset($fetched[$i])) {
$row = pg_fetch_assoc($result);
echo "Verbindung $i lieferte: " . $row['id'] . PHP_EOL;
$fetched[$i] = true;
$done++;
}
}
}
}
$read = $sockets; // zurücksetzen
}
pg_close($conn1);
pg_close($conn2);
// Wichtig · Fallstricke
Nicht schließen: Das von pg_socket() zurückgegebene Socket-Handle gehört der internen PostgreSQL-Verbindungsressource. Ein Aufruf von fclose() oder socket_close() auf diesem Handle würde die PostgreSQL-Verbindung beschädigen und zu undefiniertem Verhalten führen.
Nur lesend: Das Handle ist als Nur-Lese-Handle konzipiert. Es darf nicht zum Senden von Daten direkt auf das Socket verwendet werden – alle Kommunikation mit PostgreSQL muss über die pg_*()-Funktionen erfolgen.
pg_consume_input() nicht vergessen: Nach dem Erkennen von Aktivität auf dem Socket sollte pg_consume_input() aufgerufen werden, bevor pg_connection_busy() geprüft wird, um den internen Puffer der libpq-Bibliothek zu aktualisieren.
PHP 8.0+: Ab PHP 8.0 wird PgSql\Connection statt einer Ressource verwendet. Das zurückgegebene Socket-Objekt ist vom Typ Socket (ehemals Ressource vom Typ stream).