Maison > Questions et réponses > le corps du texte
J'essaie d'insérer des valeurs dans une table de contenu. Cela fonctionne bien s'il n'y a pas de variables PHP dans VALUES. Cependant, lorsque j'y mets la variable $type
放在VALUES
, cela ne fonctionne pas. Qu'ai-je fait de mal?
$type = 'testing'; mysql_query("INSERT INTO contents (type, reporter, description) VALUES($type, 'john', 'whatever')");
P粉2390894432023-09-17 12:00:21
Pour éviter l'injection SQL, l'instruction insert sera :
$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粉0368000742023-09-17 10:48:29
Les règles pour ajouter des variables PHP dans n'importe quelle instruction MySQL sont simples et directes :
Cette règle s'applique à 99 % des requêtes, et elle s'applique également à la vôtre. Toute variable qui représente un littéral de données SQL (ou simplement une chaîne ou un nombre SQL) doit être ajoutée via une instruction préparée. Sans exception.
Cette méthode se compose de quatre étapes de base :
Voici comment y parvenir dans tous les pilotes de base de données PHP populaires :
mysqli
pour ajouter des littéraux de donnéesLes 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, vous devez effectuer explicitement la préparation/la liaison/l'exécution :
$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();
Ce 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 peut beaucoup simplifier 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(); // 或者 while (...)
Cependant, si vous disposez d'une ancienne version de PHP, vous devez effectuer les routines préparer/lier/exécuter et également appeler get_result()
方法,以便从中获取一个熟悉的mysqli_result
à partir duquel les données peuvent être extraites 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(); // 或者 while (...)
$type = 'testing'; $reporter = "John O'Hara"; $query = "INSERT INTO contents (type, reporter, description) VALUES(?, ?, 'whatever')"; $stmt = $pdo->prepare($query); $stmt->execute([$type, $reporter]);
Dans PDO, nous pouvons fusionner 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.
Toutes les autres parties de la requête, telles que les mots-clés SQL, les noms de tables ou de champs, ou les opérateurs, doivent être filtrées via une 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). C'est une situation 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 votre script. Ceci est expliqué en détail dans mon autre article Ajouter des noms de champs dans la clause ORDER BY en fonction de la sélection de l'utilisateur :
Voici un exemple :
$orderby = $_GET['orderby'] ?: "name"; // 设置默认值 $allowed = ["name","price","qty"]; // 允许的字段名的白名单 $key = array_search($orderby, $allowed, true); // 看看是否有这个名字 if ($key === false) { throw new InvalidArgumentException("无效的字段名"); }
$direction = $_GET['direction'] ?: "ASC"; $allowed = ["ASC","DESC"]; $key = array_search($direction, $allowed, true); if ($key === false) { throw new InvalidArgumentException("无效的ORDER BY方向"); }
Après un code comme celui-ci, les $direction
和$orderby
variables peuvent être placé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 est que les identifiants doivent également être formatés selon la syntaxe spécifique de la base de données. Pour MySQL, les identifiants doivent être entourés de caractères backtick
. Ainsi, la chaîne de requête finale pour notre exemple ORDER BY devrait être :
$query = "SELECT * FROM `table` ORDER BY `$orderby` $direction";