Dans le développement de PHP, l'interaction de la base de données est une partie inévitable. De nombreux débutants et même certains développeurs seniors sont toujours habitués à construire des instructions SQL via l'épissage des cordes. Bien que cette méthode soit simple et intuitive, elle présente de nombreux dangers cachés en termes de sécurité, de maintenabilité et de performance. Cet article explorera pourquoi l'utilisation de MySQLI :: STMT_INIT (ou une déclaration plus largement prétraitement) est un choix plus sûr et plus efficace, et combine des cas réels pour démontrer la valeur de son application en développement.
Les méthodes traditionnelles de couture SQL sont généralement les suivantes:
$user_id = $_GET['id'];
$query = "SELECT * FROM users WHERE id = $user_id";
$result = mysqli_query($conn, $query);
Si $ user_id n'a pas été strictement vérifié et filtré, un attaquant peut facilement construire des entrées telles que 1 ou 1 = 1 , puis contourner la vérification, l'accès ou même modifier des données sensibles dans la base de données. Cette méthode d'attaque, à savoir l'injection SQL , est l'une des vulnérabilités de sécurité les plus courantes et les plus dangereuses.
Création et utilisant des instructions de prétraitement à l'aide de MySQLI :: STMT_INIT peut effectivement empêcher l'injection de SQL. Les instructions de prétraitement séparent la structure de l'instruction SQL des données des paramètres et les données des paramètres ne seront pas analysées en instructions SQL, ce qui élimine fondamentalement la possibilité d'injection:
$conn = new mysqli("localhost", "user", "password", "database");
$stmt = $conn->stmt_init();
$stmt->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param("i", $user_id);
$user_id = $_GET['id'];
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row['username'] . "<br>";
}
Dans cet exemple , ? est un espace réservé, bind_param spécifie le type de données de la variable et lie la valeur de la variable. Cette approche est non seulement sûre, mais rend également le code plus clair.
Bien que l'épissage SQL soit plus court que les instructions de prétraitement au niveau de la syntaxe, les instructions de prétraitement ont une efficacité d'exécution plus élevée à partir du niveau d'exécution de la base de données.
Lorsqu'un SQL est exécuté plusieurs fois (comme l'insertion de plusieurs enregistrements dans une boucle), la base de données peut compiler et mettre en cache des instructions de prétraitement, réduisant ainsi la compilation en double et le temps d'analyse et l'amélioration des performances globales.
$stmt = $conn->stmt_init();
$stmt->prepare("INSERT INTO logs (message, created_at) VALUES (?, ?)");
$stmt->bind_param("ss", $message, $created_at);
foreach ($logs as $log) {
$message = $log['msg'];
$created_at = $log['time'];
$stmt->execute();
}
En revanche, si vous utilisez des instructions d'épissage, la base de données doit être revu et compiler SQL à chaque fois, gaspillant ainsi les ressources.
Lorsque le projet est complexe dans une certaine mesure, il y aura de plus en plus de variables et de types de données dans les instructions SQL. L'utilisation de STMT_INIT et ses méthodes de support peuvent rendre la liaison des paramètres et la séparation variable plus intuitive, et plus pratique pour le débogage et la maintenance.
De plus, lorsque vous utilisez des instructions de prétraitement, le type de données des paramètres doit être explicitement transmis à bind_param , ce qui peut réduire les erreurs causées par des types de données incohérents dans une certaine mesure et améliorer la robustesse du code.
Dans les projets réels, l'URL est l'entrée principale de l'entrée des paramètres, par exemple:
https://m66.net/user.php?id=1
Si ce type d'URL est épissé directement en SQL via $ _get ['id'] , il est très facile de devenir un point d'attaque. La déclaration de prétraitement garantit que même si l'attaquant entre quelque chose de similaire:
https://m66.net/user.php?id=1 OR 1=1
Le système peut toujours reconnaître correctement l'intégralité de l'entrée en tant que paramètre de chaîne sans être exécuté sous forme d'instruction SQL par la base de données, protégeant fondamentalement la sécurité du système.
Dans le développement du projet PHP, le choix de la méthode d'interaction de la base de données correcte est cruciale pour la sécurité, la stabilité et les performances du système. Bien que MySQLI :: STMT_INIT et les déclarations de prétraitement puissent sembler un peu lourds au début, les avantages de sécurité et les améliorations des performances qu'il apporte sont des garanties indispensables pour tout projet de développement sérieux.
Au lieu de compenser la perte par la suite, il est préférable de poser une base solide depuis le début - abandonner SQL et d'adopter des instructions de prétraitement pour rendre le code plus sûr, plus efficace et fiable.