Start · Sprachen · PHP · Referenz · pg_escape_identifier

pg_escape_identifier

Funktion

Maskiert einen PostgreSQL-Bezeichner (z. B. Tabellen- oder Spaltennamen) sicher für die Verwendung in SQL-Abfragen.

seit PHP 5.4.4 Kategorie: db

Signatur

pg_escape_identifier(PgSql\Connection|string $connection_or_string, string $string = ''): string

Beschreibung

pg_escape_identifier() maskiert einen Bezeichner – beispielsweise einen Tabellen- oder Spaltennamen – so, dass er sicher in einer SQL-Abfrage verwendet werden kann. Die Funktion umschließt den Bezeichner mit doppelten Anführungszeichen (") und maskiert darin enthaltene doppelte Anführungszeichen durch Verdoppelung.

Im Unterschied zu pg_escape_string(), die für Werte in SQL-Literalen gedacht ist, wird pg_escape_identifier() ausschließlich für SQL-Bezeichner (Identifier) eingesetzt, also für Namen von Tabellen, Schemata, Spalten oder anderen Datenbankobjekten. Eine Verwechslung beider Funktionen kann zu falscher Maskierung und damit zu SQL-Injection-Lücken führen.

Die Funktion berücksichtigt die Zeichenkodierung der aktuellen PostgreSQL-Verbindung und ist daher der manuellen String-Manipulation oder dem Umwickeln in Anführungszeichen ohne Maskierung stets vorzuziehen. Sind Bezeichner vollständig statisch und nicht benutzergesteuert, ist die Funktion dennoch empfehlenswert, um versehentliche Sonderfälle (z. B. Groß-/Kleinschreibung, reservierte Wörter) sicher zu behandeln.

Seit PHP 8.1 ist der erste Parameter vom Typ PgSql\Connection; in früheren Versionen war es eine Ressource. Wird der $connection-Parameter weggelassen, nutzt PHP die zuletzt geöffnete PostgreSQL-Verbindung.

Parameter

Name Typ Default Beschreibung
$connection_or_string PgSql\Connection|string Eine aktive PostgreSQL-Verbindung (empfohlen) oder – bei Aufruf mit nur einem Argument – direkt der zu maskierende Bezeichner als string. Wird die Verbindung weggelassen, verwendet PHP die zuletzt geöffnete Verbindung.
$string string Der zu maskierende Bezeichner (z. B. Tabellen- oder Spaltenname). Wird nur angegeben, wenn der erste Parameter eine Verbindung ist.

Rückgabewert

Typ
string
Beschreibung
Den maskierten Bezeichner als Zeichenkette, eingeschlossen in doppelte Anführungszeichen und mit korrekt maskierten internen Sonderzeichen. Im Fehlerfall wird false zurückgegeben (z. B. wenn keine aktive Verbindung vorhanden ist).

Beispiele

Tabellennamen aus Benutzereingabe sicher verwenden

<?php
$conn = pg_connect('host=localhost dbname=testdb user=pguser password=secret');

// Benutzerseitig übergebener Tabellenname – NIEMALS ungeprüft einfügen!
$userTable = 'user_data; DROP TABLE users; --';

$safeTable = pg_escape_identifier($conn, $userTable);
// Ergebnis: "user_data; DROP TABLE users; --"
// Das gesamte String wird als ein einzelner Bezeichner behandelt

$sql = 'SELECT * FROM ' . $safeTable . ' LIMIT 10';
echo $sql;
// SELECT * FROM "user_data; DROP TABLE users; --" LIMIT 10
// PostgreSQL wird diese Tabelle nicht finden, aber eine Injection ist verhindert

pg_close($conn);
SELECT * FROM "user_data; DROP TABLE users; --" LIMIT 10

Dynamische Spaltenauswahl mit sicherem Bezeichner

<?php
$conn = pg_connect('host=localhost dbname=testdb user=pguser password=secret');

$columns = ['first_name', 'last "name"', 'email'];

$escapedCols = array_map(
    fn(string $col): string => pg_escape_identifier($conn, $col),
    $columns
);

$sql = 'SELECT ' . implode(', ', $escapedCols) . ' FROM ' . pg_escape_identifier($conn, 'users');
echo $sql;
// SELECT "first_name", "last ""name""", "email" FROM "users"

$result = pg_query($conn, $sql);
while ($row = pg_fetch_assoc($result)) {
    print_r($row);
}

pg_close($conn);
SELECT "first_name", "last ""name""", "email" FROM "users"

// Wichtig · Fallstricke

Sicherheitshinweis: pg_escape_identifier() schützt ausschließlich Bezeichner vor SQL-Injection. Für Datenwerte in WHERE-Klauseln oder INSERT-Anweisungen muss stattdessen pg_escape_literal() oder besser vorbereitete Statements (Prepared Statements via pg_prepare() / pg_execute()) verwendet werden.

Beachte, dass PostgreSQL Bezeichner in doppelten Anführungszeichen case-sensitiv behandelt. Ein mit pg_escape_identifier() maskierter Name wie UsersTable wird als "UsersTable" interpretiert und ist damit unterschiedlich von userstable (ohne Anführungszeichen).

Die Funktion ist kein Ersatz für eine Whitelist: Wenn möglich, sollte der Tabellenname aus einer festen Liste erlaubter Namen validiert werden, bevor er in die Abfrage eingesetzt wird.