Viele ausgereifte Datenbanken unterstützen das Konzept vorbereiteter Anweisungen (Prepared Statements
). Was sind sie? Sie können sie sich als kompilierte, auszuführende SQL-Anweisungsvorlage vorstellen, die mit verschiedenen variablen Parametern angepasst werden kann. Vorbereitete Anweisungen haben zwei Hauptvorteile:
Abfragen müssen nur einmal geparst (oder vorbereitet) werden, können aber mehrmals mit denselben oder unterschiedlichen Parametern ausgeführt werden. Wenn die Abfrage vorbereitet ist, analysiert, kompiliert und optimiert die Datenbank ihren Plan zur Ausführung der Abfrage. Wenn Sie bei komplexen Abfragen wiederholt Abfragen mit unterschiedlichen Parametern, aber derselben Struktur ausführen müssen, nimmt dieser Vorgang viel Zeit in Anspruch und führt zu einer Verlangsamung Ihrer Anwendung. Durch die Verwendung einer vorbereiteten Anweisung können Sie wiederholte Analysen, Kompilierungen und Optimierungen vermeiden. Einfach ausgedrückt verbrauchen vorbereitete Anweisungen weniger Ressourcen und werden schneller ausgeführt.
Parameter, die an vorbereitete Anweisungen übergeben werden, müssen nicht in Anführungszeichen gesetzt werden, der zugrunde liegende Treiber übernimmt dies für Sie. Wenn Ihre Anwendung ausschließlich vorbereitete Anweisungen verwendet, können Sie sicher sein, dass keine SQL-Injection erfolgt. (Wenn Sie jedoch immer noch andere Teile der Abfrage auf der Grundlage nicht vertrauenswürdiger Eingaben erstellen, ist dies immer noch riskant.)
Da vorbereitete Anweisungen so nützlich sind, sind sie das Einzige, was PDO für von Datenbanken bereitgestellte Mock-Implementierungen tut die diese Funktion nicht unterstützen. Dadurch können Sie eine einheitliche Datenzugriffsspezifikation verwenden, ohne sich Gedanken darüber machen zu müssen, ob die Datenbank selbst über diese Funktion verfügt.
/* 使用预处理语句重复插入数据(1) 此示例演示了一个通过向命名占位符代入一个name和一个value值来执行的INSERT查询 */ 连接数据库:$dbh = new PDO("mysql:host=127.0.0.1;dbname=dbname",'username','123'); 注:如果插入数据后出现乱码的话,注意检查各个页面的字符集设置,尤其是关于pdo处理的php页面仅有header头设置为utf-8有时也不行,这时就在执行SQL语句前设置数据库的字符集$dbh->query("set names utf8"); $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(); /* 使用预处理语句重复插入数据(2) 此示例演示了一个通过向用?表示的占位符代入一个name和一个value值来执行的INSERT查询 */ $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(); /* 通过预处理语句获取数据 此示例演示使用从表单获取的数据为关键值来执行查询获取数据。用户的输入会被自动添加引号,所以这儿不存在SQL注入攻击的危险。 */ $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, können Sie Ausgabeparameter auch auf die gleiche Weise wie Eingabeparameter binden. Ausgabeparameter werden häufig als Rückgabewerte von gespeicherten Prozeduren verwendet. Ausgabeparameter sind etwas komplizierter zu verwenden als Eingabeparameter. Wenn Sie sie verwenden, müssen Sie die Größe des zurückgegebenen Parameterwerts kennen. Wenn ein größerer Parameterwert als von Ihnen vorgeschlagen zurückgegeben wird, tritt ein Fehler auf.
//调用一个带有输出参数的存储过程 $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 Ausgabe darstellen. Die Syntax ähnelt den Ausgabeparametern. Im nächsten Codebeispiel wird die Zeichenfolge „hello“ an die gespeicherte Prozedur übergeben und bei der Rückgabe wird „hello“ durch den Rückgabewert der gespeicherten Prozedur ersetzt.
//调用一个带有输入/输出参数的存储过程 $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"; //占位符的错误使用 $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]%”));
Wenn es einen Fehler gibt, weisen Sie ihn bitte darauf hin. Wenn Sie weitere verwandte Probleme erfahren möchten, besuchen Sie bitte die chinesische PHP-Website: PHP-Video-Tutorial,
Ich glaube, dass es reich an Inhalten und Erklärungen ist und Ihnen eine zufriedenstellende Antwort geben wird.
Das obige ist der detaillierte Inhalt vonWas sind vorbereitete Aussagen? Wie benutzt man es?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!