Maison > Questions et réponses > le corps du texte
P粉9498488492023-08-24 16:07:56
Pour éviter l'injection SQL, insérez des instructions avec be
$type = 'testing'; $name = 'john'; $description = 'whatever'; $con = new mysqli($user, $pass, $db); $stmt = $con->prepare("INSERT INTO contents (type, reporter, description) VALUES (?, ?, ?)"); $stmt->bind_param("sss", $type , $name, $description); $stmt->execute();
P粉8832233282023-08-24 15:43:16
Les règles pour ajouter des variables PHP à n'importe quelle instruction MySQL sont simples et directes :
Cette règle couvre 99% des requêtes, notamment la vôtre. Toutes les variables représentant des littéraux de données SQL (ou, simplement - des chaînes ou des nombres SQL) doivent être ajoutées via des instructions préparées. Aucune exception.
Cette méthode comporte quatre étapes de base
Voici comment procéder en utilisant tous les pilotes de base de données PHP populaires :
mysqli
Les versions actuelles de PHP vous permettent de préparer/lier/exécuter en un seul appel :
$type = 'testing'; $reporter = "John O'Hara"; $query = "INSERT INTO contents (type, reporter, description) VALUES(?, ?, 'whatever')"; $mysqli->execute_query($query, [$type, $reporter]);
Si vous disposez d'une ancienne version de PHP, la préparation/liaison/exécution doit être effectuée explicitement :
$type = 'testing'; $reporter = "John O'Hara"; $query = "INSERT INTO contents (type, reporter, description) VALUES(?, ?, 'whatever')"; $stmt = $mysqli->prepare($query); $stmt->bind_param("ss", $type, $reporter); $stmt->execute();
Le code est un peu complexe, mais une explication détaillée de tous ces opérateurs peut être trouvée dans mon article, Comment exécuter une requête INSERT à l'aide de Mysqli, ainsi qu'une solution qui simplifie considérablement le processus.
Pour les requêtes SELECT, vous pouvez utiliser la même méthode que ci-dessus :
$reporter = "John O'Hara"; $result = $mysqli->execute_query("SELECT * FROM users WHERE name=?", [$reporter]); $row = $result->fetch_assoc(); // or while (...)
Cependant, si vous disposez d'une ancienne version de PHP, vous devrez effectuer une routine préparer/lier/exécuter et ajouter la paire get_result()
方法的调用,以获得熟悉的< code>mysqli_result Vous pouvez en récupérer les données de la manière habituelle :
$reporter = "John O'Hara"; $stmt = $mysqli->prepare("SELECT * FROM users WHERE name=?"); $stmt->bind_param("s", $reporter); $stmt->execute(); $result = $stmt->get_result(); $row = $result->fetch_assoc(); // or while (...)
$type = 'testing'; $reporter = "John O'Hara"; $query = "INSERT INTO contents (type, reporter, description) VALUES(?, ?, 'whatever')"; $stmt = $pdo->prepare($query); $stmt->execute([$type, $reporter]);
En PDO, nous pouvons combiner les parties de liaison et d'exécution, ce qui est très pratique. PDO prend également en charge les espaces réservés nommés, ce que certaines personnes trouvent très pratique.
Toute autre partie de la requête, telle que les mots-clés SQL, les noms de tables ou de champs, ou les opérateurs, doit être filtrée via liste blanche.
Parfois, nous devons ajouter une variable qui représente une autre partie de la requête, comme un mot-clé ou un identifiant (nom de base de données, de table ou de champ). Cette situation est rare, mais il vaut mieux être préparé.
Dans ce cas, votre variable doit être vérifiée par rapport à la liste de valeurs explicitement écrites dans le script. Ceci est expliqué dans mon autre article Ajout de noms de champs dans la clause ORDER BY en fonction de la sélection de l'utilisateur :
Voici un exemple :
$orderby = $_GET['orderby'] ?: "name"; // set the default value $allowed = ["name","price","qty"]; // the white list of allowed field names $key = array_search($orderby, $allowed, true); // see if we have such a name if ($key === false) { throw new InvalidArgumentException("Invalid field name"); }
$direction = $_GET['direction'] ?: "ASC"; $allowed = ["ASC","DESC"]; $key = array_search($direction, $allowed, true); if ($key === false) { throw new InvalidArgumentException("Invalid ORDER BY direction"); }
Après un code comme celui-ci, $direction
和 $orderby
les variables peuvent être insérées en toute sécurité dans la requête SQL car soit elles seront égales à l'une des variantes autorisées, soit une erreur sera générée.
Une dernière chose à mentionner à propos des identifiants est qu'ils doivent également être formatés selon la syntaxe spécifique de la base de données. Pour MySQL, il doit s'agir des caractères 反引号
entourant l'identifiant. La chaîne de requête finale pour notre exemple de commande sera donc
$query = "SELECT * FROM `table` ORDER BY `$orderby` $direction";