Heim > Artikel > Backend-Entwicklung > PHP – PDO-vorbereitete Anweisungen und gespeicherte Prozeduren
Viele ausgereiftere Datenbanken unterstützen das Konzept vorbereiteter Aussagen. Was sind vorbereitete Aussagen? Betrachten Sie es als eine kompilierte Vorlage des SQL, das Sie ausführen möchten, das mithilfe variabler Parameter angepasst werden kann. Vorbereitete Anweisungen können zwei große Vorteile bringen:
Abfragen müssen nur einmal geparst (oder vorverarbeitet) werden, können aber mehrmals mit denselben oder unterschiedlichen Parametern ausgeführt werden. Wenn eine Abfrage bereit ist, analysiert, kompiliert und optimiert die Datenbank den Plan zur Ausführung der Abfrage. Dieser Vorgang dauert bei komplexen Abfragen länger und kann Ihre Anwendung erheblich verlangsamen, wenn dieselbe Abfrage mehrmals mit unterschiedlichen Parametern wiederholt werden muss. Durch die Verwendung vorbereiteter Anweisungen können Sie wiederholte Analyse-/Kompilierungs-/Optimierungszyklen vermeiden. Einfach ausgedrückt verbrauchen vorbereitete Anweisungen weniger Ressourcen und werden daher schneller ausgeführt.
Parameter, die für vorbereitete Anweisungen bereitgestellt werden, müssen nicht in Anführungszeichen gesetzt werden, der Treiber verarbeitet sie automatisch. Wenn Ihre Anwendung nur vorbereitete Anweisungen verwendet, können Sie sicher sein, dass keine SQL-Injection erfolgt. (Wenn jedoch andere Teile der Abfrage aus nicht maskierten Eingaben erstellt werden, besteht immer noch das Risiko einer SQL-Injection.)
Vorbereitete Anweisungen sind so nützlich, dass ihre einzige Funktion darin besteht, dass PDO die Verarbeitung simuliert, wenn der Treiber dies nicht unterstützt. Dadurch wird sichergestellt, dass Anwendungen dasselbe Datenzugriffsmuster verwenden können, unabhängig davon, ob die Datenbank über solche Funktionen verfügt.
Beispiel #1 Verwenden Sie vorbereitete Anweisungen, um wiederholte Einfügungen durchzuführen
Das folgende Beispiel führt eine Einfügungsabfrage aus, indem die entsprechenden benannten Platzhalter durch Namen und Werte 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(); ?>
Beispiel # 2 Wiederholtes Einfügen mit vorbereiteten Anweisungen
Das folgende Beispiel führt eine Einfügeabfrage aus, indem die ?-Platzhalterposition durch Name und Wert ersetzt wird.
<?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(); ?>
Beispiel #3 Verwenden Sie vorbereitete Anweisungen, um Daten zu erhalten
Das folgende Beispiel ruft Daten basierend auf dem bereitgestellten Schlüsselwert ab. Benutzereingaben werden automatisch in Anführungszeichen gesetzt, 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 zu erhalten. Ausgabeparameter sind etwas komplizierter zu verwenden als Eingabeparameter, da Sie beim Binden eines Ausgabeparameters die Länge des angegebenen Parameters kennen müssen. Wenn der an einen Parameter gebundene Wert größer als die empfohlene Länge ist, wird ein Fehler generiert.
Beispiel #4 Aufrufen einer gespeicherten Prozedur 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 Parameter auch sowohl mit Eingabe- als auch mit Ausgabewerten angeben, und die Syntax ähnelt den Ausgabeparametern. Im nächsten Beispiel wird die Zeichenfolge „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.
Beispiel #5 Aufruf einer gespeicherten Prozedur 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"; ?>
Beispiel #6 Ungültige Verwendung von Platzhaltern
<?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]%")); ?>