Concaténer directement une valeur saisie par un visiteur dans une chaîne SQL revient à laisser la porte grande ouverte : rien n’empêche cette valeur de contenir elle-même du code SQL supplémentaire, capable d’altérer la requête d’origine. Séparer nettement la structure de la requête et ses valeurs neutralise ce risque à la racine.
La méthode prepare() de $wpdb
Dans WordPress, cette technique passe par la méthode $wpdb->prepare(), qui accepte une chaîne contenant des espaces réservés (%s pour une chaîne, %d pour un entier, %f pour un nombre décimal) suivis des valeurs correspondantes. La méthode échappe et met en forme chaque valeur selon son type avant de reconstituer une requête sûre à exécuter.
Exemple
<?php
global $wpdb;
$resultats = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$wpdb->posts} WHERE post_author = %d AND post_status = %s",
$auteur_id,
'publish'
)
);
Pièges fréquents
- Les noms de table ou de colonne ne peuvent pas être passés en paramètre : ils doivent être insérés directement dans la chaîne, en les validant vous-même contre une liste connue à l’avance.
- Oublier les guillemets simples autour d’un espace réservé
%sdans la chaîne d’origine n’est pas nécessaire :prepare()les ajoute automatiquement, contrairement à une idée reçue répandue. - Passer un tableau de valeurs directement à
prepare()sans le déployer avec l’opérateur...(spread) provoque une erreur silencieuse sur le nombre d’espaces réservés. - Cette méthode ne dispense pas d’échapper le résultat à l’affichage : sécuriser une requête SQL et sécuriser une sortie HTML restent deux étapes distinctes, chacune avec ses propres fonctions dédiées.