PHP PDO Prepared Statements und gespeicherte Prozeduren

PHP PDO 参考手册PHP PDO-Referenzhandbuch

Viele ausgereiftere Datenbanken unterstützen das Konzept der vorbereiteten Anweisungen.

Was ist eine vorbereitete Anweisung? Man kann sie sich als eine kompilierte Vorlage des SQL vorstellen, das Sie ausführen möchten, und die mit variablen Parametern angepasst werden kann. Vorbereitete Anweisungen bieten zwei wesentliche Vorteile:

  • Die Abfrage muss nur einmal geparst (oder vorverarbeitet) werden, kann aber mehrmals mit denselben oder unterschiedlichen Parametern ausgeführt werden. Wenn die Abfrage vorbereitet wird, analysiert, kompiliert und optimiert die Datenbank den Plan zur Ausführung der Abfrage. Bei komplexen Abfragen kann dieser Prozess lange dauern. Wenn dieselbe Abfrage viele Male mit unterschiedlichen Parametern wiederholt werden muss, verlangsamt dieser Prozess die Anwendung erheblich. Durch die Verwendung vorbereiteter Anweisungen können wiederholte Analyse-/Kompilierungs-/Optimierungszyklen vermieden werden. Kurz gesagt, vorbereitete Anweisungen verbrauchen weniger Ressourcen und laufen daher schneller.
  • Parameter, die an vorbereitete Anweisungen übergeben werden, müssen nicht in Anführungszeichen eingeschlossen werden; der Treiber übernimmt dies automatisch. Wenn eine Anwendung ausschließlich vorbereitete Anweisungen verwendet, können Sie sicher sein, dass keine SQL-Injection auftritt. (Wenn jedoch andere Teile der Abfrage aus nicht maskierten Eingaben zusammengesetzt werden, besteht weiterhin die Gefahr von SQL-Injection.)

Vorbereitete Anweisungen sind so nützlich, dass sie die einzige Funktion sind, die PDO emuliert, wenn der Treiber sie nicht unterstützt. Dadurch wird sichergestellt, dass die Anwendung unabhängig davon, ob die Datenbank über diese Funktionalität verfügt, dasselbe Datenzugriffsmuster verwenden kann.

Ausführen wiederholter Einfügungen mit vorbereiteten Anweisungen

Das folgende Beispiel führt eine Einfügeabfrage aus, indem die entsprechenden benannten Platzhalter durch Name und Wert ersetzt werden.

<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);

// 插入一行
$name = 'one';
$value = 1;
$stmt->execute();

//  用不同的值插入另一行
$name = 'two';
$value = 2;
$stmt->execute();
?>

Ausführen wiederholter Einfügungen mit vorbereiteten Anweisungen

Das folgende Beispiel führt eine Einfügeabfrage aus, indem die ?-Platzhalter durch Name und Wert ersetzt werden.

<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);

// 插入一行
$name = 'one';
$value = 1;
$stmt->execute();

// 用不同的值插入另一行
$name = 'two';
$value = 2;
$stmt->execute();
?>

Abrufen von Daten mit vorbereiteten Anweisungen

Das folgende Beispiel ruft Daten basierend auf bereitgestellten Schlüsselwerten ab. Die Eingabe des Benutzers wird automatisch in Anführungszeichen eingeschlossen, sodass keine Gefahr von SQL-Injection-Angriffen besteht.

<?php
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
if ($stmt->execute(array($_GET['name']))) {
  while ($row = $stmt->fetch()) {
    print_r($row);
  }
}
?>

Wenn der Datenbanktreiber dies unterstützt, kann die Anwendung auch Ausgabe- und Eingabeparameter binden. Ausgabeparameter werden normalerweise verwendet, um Werte aus gespeicherten Prozeduren abzurufen. Ausgabeparameter sind etwas komplexer zu verwenden als Eingabeparameter, denn wenn ein Ausgabeparameter gebunden wird, müssen Sie die Länge des angegebenen Parameters kennen. Wenn der an den Parameter gebundene Wert größer als die vorgeschlagene Länge ist, wird ein Fehler erzeugt.

Aufrufen gespeicherter Prozeduren mit Ausgabeparametern

<?php
$stmt = $dbh->prepare("CALL sp_returns_string(?)");
$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000); 

// 调用存储过程
$stmt->execute();

print "procedure returned $return_value\n";
?>

Sie können auch Parameter angeben, die sowohl Eingabe- als auch Ausgabewerte haben, mit einer Syntax ähnlich der für Ausgabeparameter. Im nächsten Beispiel wird die Zeichenkette "hello" an die gespeicherte Prozedur übergeben, und wenn die gespeicherte Prozedur zurückkehrt, wird hello durch den von der gespeicherten Prozedur zurückgegebenen Wert ersetzt.

Aufrufen gespeicherter Prozeduren mit Eingabe-/Ausgabeparametern

<?php
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'hello';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000); 

// 调用存储过程
$stmt->execute();

print "procedure returned $value\n";
?>

Ungültige Verwendung eines Platzhalters

<?php
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'");
$stmt->execute(array($_GET['name']));

// 占位符必须被用在整个值的位置
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE ?");
$stmt->execute(array("%$_GET[name]%"));
?>

PHP PDO 参考手册PHP PDO-Referenzhandbuch

Andere Erweiterungen