query
führt eine Standard-SQL-Anweisung aus und erfordert, dass Sie alle Daten ordnungsgemäß maskieren, um SQL-Injections und andere Probleme zu vermeiden.
execute
führt eine vorbereitete Anweisung aus, mit der Sie Parameter binden können, um zu vermeiden, dass die Parameter maskiert oder in Anführungszeichen gesetzt werden müssen. execute
Dies ist auch dann besser, wenn Sie eine Abfrage mehrmals wiederholen. Beispiel für vorbereitete Aussagen:
$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories);
$sth->bindParam(':colour', $colour);
$sth->execute();
// $calories or $color do not need to be escaped or quoted since the
// data is separated from the query
Es wird empfohlen, sich an vorbereitete Aussagen zu halten und execute
die Sicherheit zu erhöhen .
Siehe auch: Reichen PDO-vorbereitete Anweisungen aus, um eine SQL-Injection zu verhindern?
: calories
, entspricht diesmysql_real_escape_string()
dem Absetzen von Injektionen, oder benötigen Sie mehr als nur$sth->bindParam(':calories', $calories);
die Sicherheit?query
ein PDOStatement anstelle eines Bool- ähnlichen zurückgegebenexecute
?Nein, sie sind nicht gleich. Abgesehen von der Escape-Funktion auf der Clientseite, die bereitgestellt wird , wird eine vorbereitete Anweisung auf der Serverseite einmal kompiliert und kann dann bei jeder Ausführung an andere Parameter übergeben werden. Was bedeutet, dass Sie Folgendes tun können:
Sie führen im Allgemeinen zu einer Leistungsverbesserung, obwohl sie im kleinen Maßstab nicht erkennbar sind. Lesen Sie mehr über vorbereitete Anweisungen (MySQL-Version) .
quelle
Gileans Antwort ist großartig, aber ich wollte nur hinzufügen, dass es manchmal seltene Ausnahmen zu Best Practices gibt, und Sie möchten möglicherweise Ihre Umgebung in beide Richtungen testen, um herauszufinden, was am besten funktioniert.
In einem Fall stellte ich fest, dass dies
query
für meine Zwecke schneller funktionierte, da ich vertrauenswürdige Daten von einer Ubuntu Linux-Box mit PHP7 mit dem schlecht unterstützten Microsoft ODBC-Treiber für MS SQL Server massenweise übertrug .Ich bin zu dieser Frage gekommen, weil ich ein lang laufendes Skript für eine ETL hatte , das ich aus Geschwindigkeitsgründen drücken wollte. Es schien mir intuitiv zu sein, dass
query
es schneller sein könnte alsprepare
&,execute
weil es nur eine Funktion anstelle von zwei aufrief. Die Parameterbindungsoperation bietet einen hervorragenden Schutz, kann jedoch teuer sein und möglicherweise vermieden werden, wenn dies nicht erforderlich ist.Angesichts einiger seltener Bedingungen :
Wenn Sie eine vorbereitete Anweisung nicht wiederverwenden können, weil sie vom Microsoft ODBC-Treiber nicht unterstützt wird .
Wenn Sie sich keine Sorgen über die Bereinigung von Eingaben machen und ein einfaches Entkommen möglich ist, ist dies akzeptabel. Dies kann der Fall sein, da das Binden bestimmter Datentypen vom Microsoft ODBC-Treiber nicht unterstützt wird .
PDO::lastInsertId
wird vom Microsoft ODBC-Treiber nicht unterstützt.Hier ist eine Methode, mit der ich meine Umgebung getestet habe, und hoffentlich können Sie sie oder etwas Besseres in Ihrer replizieren:
Zu Beginn habe ich eine Basistabelle in Microsoft SQL Server erstellt
Und jetzt ein grundlegender zeitgesteuerter Test für Leistungsmetriken.
Ich habe mit mehreren verschiedenen Testversionen und Zählungen in meiner spezifischen Umgebung gespielt und erhalte durchweg zwischen 20 und 30% schnellere Ergebnisse
query
alsprepare
/execute
Ich bin gespannt, wie sich dieser Test in anderen Umgebungen wie MySQL verhält.
quelle