Moin Moin!
@Alexander: strict und warnings verwende ich selbstverständlich. Warum Platzhalter eine SQL-Injection verhindern sollen?: Ist das auch so eine Annahme von Dir,
Nein, eine definierte API:
RDBMS, deren Native-API Platzhalter vorsieht, werden von DBDs exakt so angesteuert, sprich: SQL-Statement und Parameter werden getrennt voneinander übermittelt, quoting ist überhaupt nicht notwendig. Das RDBMS kann von sich aus das Statement cachen und sich bei einem erneuten Aufruf das Parsen des SQL-Textes komplett sparen. DBI kann das Statement cachen, wenn prepare_cached() direkt oder indirekt benutzt wird.
RDBMS, deren Native-API keine Platzhalter vorsieht (was mittlerweile selten ist), benötigen etwas Unterstützung vom DBD. Dieser ersetzt die Platzhalter im SQL-Statement durch für das RDBMS passend gequotete Parameter. Das RDBMS kann natürlich nicht mehr sinnvoll cachen, wohl aber der DBD, insbesondere wenn prepare_cached() benutzt wird. In der Regel geschieht das Quoten und Einsetzen der Parameter in schnellem XS-Code.
In beiden Fällen werden die Parameter so zur Datenbank gebracht, dass SQL Injection unmöglich ist -- im ersten Fall werden die Parameter nicht als Teil des SQL-Statements angesehen, im zweiten Fall kümmert sich der RBDMS-spezifische Quoting-Algorithmus um *ALLE* problematischen Zeichen in den Parametern.
Es gibt nur zwei Möglichkeiten, sich eine SQL Injection mit DBI "einzufangen": Fehlerhafte DBDs oder fehlerhafte Scripts. Ersteres ist recht unwahrscheinlich, da große Teile des DBD-Codes generiert werden und/oder von einer Basisklasse erben. Letzteres passiert, wenn uralter Code kopiert wird oder der Coder die alte PHP-Denkweise nicht loslassen kann.
Weitere Diskussion: http://www.perlmonks.org/index.pl?node_id=7548&lastnode_id=864, http://www.perl.com/pub/a/1999/10/DBI.html
Alexander
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".