Les instructions préparées sont très utiles contre les injections SQL.
Préparation des commandes et des paramètres liés
Une instruction préparée est une fonction utilisée pour exécuter les mêmes (or similar) des instructions SQL à plusieurs reprises avec une grande efficacité.
Les instructions préparées fonctionnent essentiellement comme suit:
- Préparer: Un modèle de déclaration SQL est créé et envoyé à la base de données. Certaines valeurs ne sont pas spécifiés, appelés paramètres (labeled "?") la (labeled "?") . Exemple: INSERT INTO MyGuests VALUES(?, ?, ?)
- La base de données parse, compile et exécute l'optimisation des requêtes sur le modèle de l'instruction SQL, et stocke le résultat sans l'exécuter
- Exécuter: Au plus tard, l'application lie les valeurs aux paramètres, et la base de données exécute l'instruction. L'application peut exécuter l'instruction autant de fois qu'il veut avec des valeurs différentes
Par rapport à l'exécution d'instructions SQL directement, les déclarations préparées ont deux principaux avantages:
- Les instructions préparées réduit le temps que la préparation analyse syntaxique de la requête est effectuée une seule fois (although the statement is executed multiple times)
- paramètres liés réduisent au minimum la bande passante sur le serveur que vous suffit d'envoyer les paramètres à chaque fois, et non toute la requête
- Les instructions préparées sont très utiles contre les injections SQL, parce que les valeurs des paramètres, qui sont transmises ultérieurement à l'aide d'un autre protocole, ne doivent pas être correctement échappé. Si le modèle de déclaration d'origine ne provient pas d'une entrée externe, l'injection SQL ne peut pas se produire.
Les déclarations ont MySQLi
L'exemple suivant utilise des instructions préparées et des paramètres liés à MySQLi:
Exemple (MySQLi with Prepared Statements) commandes (MySQLi with Prepared Statements)
<?php
$servername = "localhost";
$username = "username";
$password =
"password";
$dbname =
"myDB";
// Create connection
$conn = new mysqli($servername,
$username, $password, $dbname);
// Check connection
if ($conn->connect_error)
{
die("Connection failed: " . $conn->connect_error);
}
// prepare and bind
$stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email)
VALUES (?, ?, ?)");
$stmt->bind_param("sss", $firstname, $lastname,
$email);
// set parameters and execute
$firstname = "John";
$lastname
= "Doe";
$email = "[email protected]";
$stmt->execute();
$firstname
= "Mary";
$lastname = "Moe";
$email = "[email protected]";
$stmt->execute();
$firstname = "Julie";
$lastname = "Dooley";
$email = "[email protected]";
$stmt->execute();
echo "New records created successfully";
$stmt->close();
$conn->close();
?>
lignes de code pour expliquer l'exemple ci-dessus:
"INSERT INTO MyGuests (firstname, lastname, email) VALUES (?, ?, ?)"
Dans notre SQL, nous insérons un point d'interrogation (?) Où nous voulons substituer un entier, chaîne, valeur double ou blob.
Ensuite, jetez un oeil à la bind_param() fonction:
$stmt->bind_param("sss", $firstname, $lastname, $email);
Cette fonction lie les paramètres à la requête SQL et la base de données indique quels sont les paramètres. Le "sss" l' argument énumère les types de données que les paramètres sont. Le caractère s mysql indique que le paramètre est une chaîne.
L'argument peut être l'un des quatre types:
- i - nombre entier
- d - le double
- s - chaîne
- b - blob
Nous devons avoir un de ces pour chaque paramètre.
En disant mysql quel type de données à attendre, nous réduisons le risque d'injections SQL.
Remarque: Si nous voulons insérer des données provenant de sources externes (like user input) l' (like user input) , il est très important que les données sont désinfecté et validé.
Les déclarations ont AOP
L'exemple suivant utilise des instructions préparées et des paramètres liés à AOP:
Exemple (PDO with Prepared Statements) commandes (PDO with Prepared Statements)
<?php
$servername = "localhost";
$username = "username";
$password =
"password";
$dbname =
"myDBPDO";
try {
$conn = new PDO("mysql:host=$servername;dbname=$dbname",
$username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE,
PDO::ERRMODE_EXCEPTION);
// prepare sql and bind
parameters
$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);
// insert a row
$firstname =
"John";
$lastname = "Doe";
$email = "[email protected]";
$stmt->execute();
// insert another row
$firstname = "Mary";
$lastname = "Moe";
$email = "[email protected]";
$stmt->execute();
// insert another row
$firstname = "Julie";
$lastname = "Dooley";
$email = "[email protected]";
$stmt->execute();
echo "New records created successfully";
}
catch(PDOException $e)
{
echo "Error: " . $e->getMessage();
}
$conn = null;
?>