Heim > Artikel > Backend-Entwicklung > Warum eine PDO-Verbindung zu MySQL die Injektion verhindern kann
$stmt = $pdo->prepare('select * from user where id=?'); $id = 1; $stmt->bindParam(1,$id); $stmt - >execute();
<span style="font-size:14px;" data-filtered="filtered"></span>
In diesem Fall sendet PHP einfach die SQL-Anweisung an den MySQL-Server, Das ist anders als wir Normalerweise macht es keinen Unterschied, mysql_real_escape_string zum Escapen der Zeichenfolge zu verwenden und sie dann in eine SQL-Anweisung zu integrieren (in diesem Fall ist eine SQL-Injection, also ein Aufruf, offensichtlich immer noch möglich). PDO bereitet sich lokal in PHP auf Mysql_real_escape_string vor, um die Abfrage mit dem lokalen Einzelbyte-Zeichensatz zu betreiben. Wenn wir mit mehreren Bytes codierte Variablen übergeben, kann dies immer noch zu SQL-Injection-Schwachstellen führen (eines der Probleme in Versionen vor PHP 5.3.6). Dies erklärt auch, warum bei Verwendung von PDO ein Upgrade auf PHP 5.3.6+ empfohlen wird und der Zeichensatz in der DSN-Zeichenfolge angegeben werden sollte besteht darin, den Zeichensatz für den MySQL-Server anzugeben und die Variablen an den MySQL-Server zu senden, um die Zeichen-Escape-Funktion auszuführen. Wird PHP lokal maskiert und zur Escape-Funktion an den MySQL-Server übergeben? mit dem Namen PDO::ATTR_EMULATE_PREPARES, der angibt, ob PHP zum Simulieren der lokalen Vorbereitung verwendet werden soll. Der Standardwert dieses Parameters ist Unknown. Und gemäß den Ergebnissen der Paketerfassung, die wir gerade erstellt haben, verwendet PHP 5.3.6+ immer noch lokale Variablen zum Konvertieren und Spleißen Sie sie in SQL, um sie an den MySQL-Server zu senden.
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);$stmt = $pdo->prepare('select * from user where id=?'); $id = 1; $stmt->bindParam(1,$id); $stmt - >execute();
Dieses Mal sendet PHP die SQL-Vorlage und die Variablen zweimal an MySQL, und MySQL schließt das Escape ab Da die Variablen und die SQL-Vorlage zweimal gesendet werden, gibt es kein SQL-Injection-Problem, aber das Zeichensatzattribut muss im DSN angegeben werden, z. B.:
$pdo = new PDO('mysql:host=localhost;dbname=test;charset= utf8', 'root');
Dann stellt sich die Frage, ob der Zeichensatz im DSN angegeben ist. Müssen Sie weiterhin die festgelegten Namen 8dfab5cd353228de2a245e6f3e44b919 ausführen? Funktion:
A. Teilen Sie dem MySQL-Server mit, welche Codierung der Client (PHP-Programm) an ihn übermittelt hat
B. Wie lautet die vom Client geforderte Kodierung des Ergebnisses?
Mit anderen Worten: Wenn die Datentabelle den GBK-Zeichensatz verwendet und das PHP-Programm die UTF-8-Codierung verwendet, führen wir set name utf8 aus, bevor wir die Abfrage ausführen, und weisen den MySQL-Server an, ihn korrekt zu codieren Es ist keine programminterne Kodierungskonvertierung erforderlich. Auf diese Weise senden wir die Abfrage in UTF-8-Kodierung an den MySQL-Server, und die erhaltenen Ergebnisse liegen ebenfalls in UTF-8-Kodierung vor. Dadurch wird das Problem der Konvertierungskodierung im Programm beseitigt. Es besteht kein Zweifel, dass dadurch kein verstümmelter Code entsteht.
Was ist also die Funktion der Angabe des Zeichensatzes im DSN? Escapes Um den angegebenen Zeichensatz zu verwenden (nicht um den MySQL-Server-Kommunikationszeichensatz festzulegen), müssen Sie zum Festlegen des MySQL-Server-Kommunikationszeichensatzes auch den Befehl „Set Names 8dfab5cd353228de2a245e6f3e44b919“ verwenden.
Verwandte Empfehlungen:
ThinkPHP-Framework basierend auf einem PDO-Modus-Verbindungsdatenbank-Betriebsbeispiel
Das obige ist der detaillierte Inhalt vonWarum eine PDO-Verbindung zu MySQL die Injektion verhindern kann. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!