Déclarations préparées PHP MySQL
Les instructions préparées sont très utiles pour empêcher l'injection MySQL.
Instructions préparées et paramètres liés
Les instructions préparées sont utilisées pour exécuter plusieurs instructions SQL identiques avec une efficacité d'exécution plus élevée.
Tutoriels vidéo recommandés : "Tutoriel MySQL" http://www.php.cn/course/list/51.html
Les instructions de prétraitement fonctionnent comme suit :
Prétraitement : créez un modèle d'instruction SQL et envoyez-le à la base de données. Les valeurs réservées sont marquées du paramètre "?". Par exemple :
DANS MyGuests (prénom, nom, email) VALEURS(?, ?, ?)
-
Analyse de base de données, compilation, optimisation des requêtes sur des modèles d'instructions SQL et stockage des résultats sans les afficher.
Exécution : Enfin, la valeur liée à l'application est transmise au paramètre (marque "?") et la base de données exécute l'instruction. L'application peut exécuter l'instruction plusieurs fois si les valeurs des paramètres sont différentes.
Par rapport à l'exécution directe d'instructions SQL, les instructions préparées présentent deux avantages principaux :
Les instructions prétraitées réduisent considérablement le temps d'analyse, une seule requête a été effectuée (bien que l'instruction ait été exécutée plusieurs fois).
Les paramètres de liaison réduisent la bande passante du serveur, il vous suffit d'envoyer les paramètres de la requête au lieu de l'intégralité de l'instruction.
Les instructions prétraitées sont très utiles pour l'injection SQL, car différents protocoles sont utilisés après l'envoi des valeurs des paramètres, garantissant la légitimité des données.
Instructions préparées par MySQLi
Les exemples suivants utilisent des instructions préparées dans MySQLi et lient les paramètres correspondants :
Exemple (MySQLi utilise déclarations préparées)
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDB"; // 创建连接 $conn = new mysqli($servername, $username, $password, $dbname); // 检测连接 if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } // 预处理及绑定 $stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)"); $stmt->bind_param("sss", $firstname, $lastname, $email); // 设置参数并执行 $firstname = "John"; $lastname = "Doe"; $email = "john@example.com"; $stmt->execute(); $firstname = "Mary"; $lastname = "Moe"; $email = "mary@example.com"; $stmt->execute(); $firstname = "Julie"; $lastname = "Dooley"; $email = "julie@example.com"; $stmt->execute(); echo "新记录插入成功"; $stmt->close(); $conn->close(); ?>analyse chaque ligne de code pour l'exemple suivant :
"INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)"Dans l'instruction SQL, nous utilisons des points d'interrogation (? ), où nous pouvons remplacer points d'interrogation avec des entiers, des chaînes, des doubles et des booléens.
Ensuite, jetons un coup d'œil à la fonction bind_param() :
$stmt->bind_param("sss", $firstname, $lastname, $email);Cette fonction lie les paramètres SQL et indique à la base de données la valeur du paramètre. La colonne de paramètres "sss" gère les types de données des paramètres restants. Le caractère s indique à la base de données que le paramètre est une chaîne.
Les paramètres ont les quatre types suivants :
i - entier (type entier)
d - double (virgule flottante double précision tapez) )
s - string (string)
b - BLOB (grand objet binaire : grand objet binaire)
Chaque paramètre doit spécifier le type.
Vous pouvez réduire le risque d'injection SQL en indiquant à la base de données le type de données du paramètre.
注意: 如果你想插入其他数据(用户输入),对数据的验证是非常重要的。 |
Instructions préparées dans PDO
Dans l'exemple suivant, nous utilisons des instructions préparées et des paramètres de liaison dans PDO :
Exemple (PDO utilisant des instructions préparées)
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "myDBPDO"; try { $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); // 设置 PDO 错误模式为异常 $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 预处理 SQL 并绑定参数 $stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES (:firstname, :lastname, :email)"); $stmt->bindParam(':firstname', $firstname); $stmt->bindParam(':lastname', $lastname); $stmt->bindParam(':email', $email); // 插入行 $firstname = "John"; $lastname = "Doe"; $email = "john@example.com"; $stmt->execute(); // 插入其他行 $firstname = "Mary"; $lastname = "Moe"; $email = "mary@example.com"; $stmt->execute(); // 插入其他行 $firstname = "Julie"; $lastname = "Dooley"; $email = "julie@example.com"; $stmt->execute(); echo "新记录插入成功"; } catch(PDOException $e) { echo $sql . "<br>" . $e->getMessage(); } $conn = null; ?>