Déclarations préparées PHP MySQL
Instructions 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.
Le principe de fonctionnement des instructions préparées est le suivant :
1. 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 :
2. INSERT
INTO MyGuests (prénom, nom, email) VALUES(?, ?, ?)
3. Le modèle effectue une optimisation des requêtes et stocke les résultats sans les afficher.
4. Exécution : Enfin, transmettez la valeur liée à l'application 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 et n'effectuent qu'une seule requête (bien que l'instruction soit 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égalité 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 des instructions préparées)
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(); ?>
Analysez chaque ligne de code dans l'exemple suivant :
"INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)"
In dans l'instruction SQL, nous utilisons le point d'interrogation (?), ici nous pouvons remplacer le point d'interrogation par un entier, une chaîne, une virgule flottante double précision et une valeur booléenne.
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 des paramètres. 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 (type à virgule flottante double précision)
· s - string (string)
· b - BLOB (grand objet binaire : grand objet binaire)
Chaque paramètre doit spécifier un 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.
Remarque : Si vous souhaitez insérer d'autres données (saisie de l'utilisateur), la validation des données est très importante.
Relevés préparés en AOP
Dans les exemples suivants, nous utilisons des instructions préparées et des paramètres de liaison dans PDO :
Exemple (PDO utilise des instructions préparées)
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 . "
" . $e->getMessage(); } $conn = null; ?>