Wenn *nicht* für die Nutzung von prepared statements?
Ich bin re-engineering eines PHP-driven web site, die verwendet eine minimale Datenbank. Die ursprüngliche version verwendet "pseudo-prepared-statements" (PHP-Funktionen, die Tat, Angebotserstellung und-parameter-Ersatz) zur Verhinderung von injection-Angriffen und separaten Datenbank-Logik-von der Seite der Logik.
Es war selbstverständlich ersetzen diese ad-hoc-Funktionen mit einem Objekt, das verwendet PDO und echten prepared statements, aber nachdem ich meine Lektüre auf Sie, ich bin mir nicht so sicher. PDO-noch immer scheint wie eine gute Idee, aber eines der wichtigsten Verkaufsargumente von prepared statements ist die Möglichkeit zur Wiederverwendung... was ich nie werden. Hier ist mein setup:
- Die Aussagen sind alle trivial einfach. Die meisten sind in der form
SELECT foo,bar FROM baz WHERE quux = ? ORDER BY bar LIMIT 1
. Die komplexe Anweisung in der Menge ist einfach, drei so wählt gemeinsam mitUNION ALL
s. - Jeder Seite Treffer führt bei den meisten eine Anweisung und führt es nur einmal.
- Ich bin in einer gehosteten Umgebung und daher misstrauisch gegenüber, schlug Ihre Server, indem Sie einen "stress-tests" persönlich.
Gegeben, dass die Verwendung von prepared statements wird mindestens die doppelte Anzahl von Datenbank-Roundtrips ich mache, bin ich besser dran, Sie zu vermeiden? Kann ich PDO::MYSQL_ATTR_DIRECT_QUERY
zu vermeiden, den Aufwand für mehrere Datenbank-Reisen, unter Beibehaltung der nutzen der Parametrisierung und-Injektion? Oder tun die binary-Aufrufe verwendet, die von der vorbereiteten Anweisung API durchführen gut genug, im Vergleich zu der Ausführung nicht vorbereitete Abfragen, die ich nicht darum kümmern?
EDIT:
Danke für all die guten Ratschläge, Leute. Dies ist eine, wo ich wünschte, ich könnte mark mehr als eine Antwort als "akzeptiert" — viele verschiedene Perspektiven. Letztlich, obwohl, ich habe zu geben rick seinen wegen... ohne seine Antwort hätte ich seelig off gegangen und erledigt das völlig Falsch, Was auch nach folgenden jeden Ratschlag. 🙂
Emulierte vorbereitete Anweisungen, die ist es!
- Vorsicht: PDO emulierte vorbereitete Anweisungen sind anfällig für SQL-injection, wenn der Zeichensatz wird zur Laufzeit geändert. Siehe die Antwort und die Antwort für eine Erläuterung.
- Es ist ganz einfach: Wenn Sie wissen, der string kommt aus der Anwendung und nicht manipuliert werden können durch einen Benutzer, dann gibt es keine Notwendigkeit für vorbereitete Anweisungen, da gibt es nichts zu injizieren. Wenn Sie nicht sicher sind (schlecht, aber in größeren Projekten, die nicht vermeidbaren) verwenden Sie eine vorbereitete Anweisung.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, Sie wollen, PDO::ATTR_EMULATE_PREPARES. Schalten Sie native Datenbank prepared statements, aber immer noch erlaubt die Abfrage von Bindungen zur Vermeidung von sql-injection und halten Sie Ihr sql-sauber. Von dem was ich verstehe, PDO::MYSQL_ATTR_DIRECT_QUERY schaltet die Abfrage Bindungen vollständig.
Die heutige Regel des software-engineering:, wenn es nicht etwas für Sie tun, verwenden Sie es nicht.
Wenn nicht Verwendung von vorbereiteten Anweisungen? Wenn Sie nur gehen, um die Ausführung der Anweisung mal vor die db Verbindung geht Weg.
Wenn nicht Verwendung gebunden Abfrage-Parametern (ist das wirklich das, was die meisten Menschen verwenden Sie vorbereitete Anweisungen zu erhalten)? Ich bin geneigt zu sagen "niemals" und ich würde wirklich gerne sagen "nie", aber die Realität ist, dass die meisten Datenbanken und einige db-abstraction-Layer über bestimmte Umstände, unter denen Sie nicht zulassen, dass Sie bind-Parameter, so dass Sie gezwungen sind, nicht verwenden Sie in diesen Fällen. Zu jeder anderen Zeit, obwohl, es wird Ihr Leben vereinfachen und Ihren code sicherer zu verwenden.
Ich bin nicht vertraut mit PDO, aber ich Wette, es bietet einen Mechanismus für die Ausführung von parametrisierten Abfragen mit den Werten die in die gleiche Funktion aufrufen, wenn Sie nicht wollen, um sich vorzubereiten, führen Sie dann in einem separaten Schritt. (z.B. so Etwas wie
run_query("SELECT * FROM users WHERE id = ?", 1)
oder ähnliches.)Auch, wenn Sie mal unter die Haube schauen, die meisten db-abstraction-Layer wird bereiten Sie die Abfrage dann ausführen, selbst wenn Sie nur sagen Sie es zum ausführen einer statischen SQL-Anweisung. Also bist du wahrscheinlich nicht speichern eine Reise in die db durch die Vermeidung expliziter bereitet jedenfalls.
$dbh->prepare("SQL")->execute(array(PARAMETERS));
aber dann kann man nicht bekommen Ergebnis aus der Datenbank. (PDOStatement::execute()
gibt nur boolean (an error).Prepared statements verwendet werden von tausenden von Menschen und sind somit gut getestet (und damit kann man ableiten, Sie sind einigermaßen sicher). Ihre individuelle Lösung wird nur von Ihnen genutzt.
Die chance, dass Ihre benutzerdefinierte Lösung unsicher ist, ist ziemlich hoch. Die Verwendung von vorbereiteten Anweisungen. Sie pflegen müssen weniger code, der Weise.
Die Vorteile der prepared statements sind wie folgt:
Jedoch, prepared statements bestehen nur pro Verbindung. Es sei denn, Sie sind mit Verbindungs-pooling, es wäre kein Vorteil, wenn Sie nur eine Anweisung pro Seite. Trivial einfache Abfragen nicht profitieren würde von der effizientere transport-format, entweder.
Ich persönlich würde das nicht stören. Die pseudo-prepared statements sind wahrscheinlich zu sein nützlich für die sichere, variable zitieren Sie vermutlich stellen.
Ehrlich, ich glaube nicht, sollten Sie Sie kümmern. Aber ich erinnere mich, dass eine Reihe von PHP-data-access-frameworks unterstützt prepare-Anweisung Modi und nicht-Anweisung vorbereiten-Modi. Wenn ich mich richtig erinnere, PEAR:DB war wieder in den Tag.
Habe ich lief in das gleiche Problem wie du, und ich hatte meine eigenen Vorbehalte, so dass anstelle der Verwendung von PDO landete ich Schreibe meine eigenen Licht-Gewicht-Datenbank-Schicht, die unterstützt, vorbereitet und standard-Anweisungen und durchgeführt richtige escaping (sql-injection-Prävention) in beiden Fällen. Eine meiner anderen gripes mit bereitet ist, dass es manchmal effizienter ist, Anhängen, einige nicht-escapable-Eingang, um eine Aussage wie: ... WHERE id IN (1, 2, 3...).
Ich weiß nicht genug über PDO zu sagen, was andere Optionen, die Sie haben, es zu benutzen. Aber ich weiß, dass PHP escaping-Funktionen zur Verfügung für alle Datenbank-Anbieter es unterstützt, und man konnte Rollen Sie Ihre eigenen kleinen Schicht, die auf einem data-access-layer-stecken Sie mit.