Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment inclure une variable PHP dans une instruction MySQL

Les règles d'ajout d'une variable PHP à l'intérieur de n'importe quelle instruction MySQL sont claires et simples :

  1. Toute variable qui représente un littéral de données SQL , (ou, pour le dire simplement - une chaîne SQL ou un nombre) DOIVENT être ajoutés via une instruction préparée. Aucune exception.
  2. Toute autre partie de la requête, telle qu'un mot clé SQL, un nom de table ou de champ, ou un opérateur, doit être filtrée via une liste blanche .

Ainsi, comme votre exemple ne concerne que des littéraux de données, toutes les variables doivent être ajoutées via des espaces réservés (également appelés paramètres). Pour ce faire :

  • Dans votre instruction SQL, remplacez toutes les variables par des espaces réservés
  • préparer la requête résultante
  • lier variables en espaces réservés
  • exécuter la requête

Et voici comment le faire avec tous les pilotes de base de données PHP populaires :

Ajout de littéraux de données à l'aide de mysql ext

Un tel pilote n'existe pas .

Ajout de littéraux de données à l'aide de mysqli

$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 compliqué mais l'explication détaillée de tous ces opérateurs se trouve dans mon article, How to run an Requête INSERT avec Mysqli , ainsi qu'une solution qui facilite considérablement le processus.

Pour une requête SELECT, vous n'aurez qu'à ajouter un appel à get_result() méthode pour obtenir un mysqli_result familier à partir duquel vous pouvez 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 (...)

Ajout de littéraux de données à l'aide de PDO

$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 combiner les parties bind et execute, ce qui est très pratique. PDO prend également en charge les espaces réservés nommés que certains trouvent extrêmement pratiques.

Ajouter des mots-clés ou des identifiants

Parfois, nous devons ajouter une variable qui représente une autre partie d'une requête, comme un mot-clé ou un identifiant (une base de données, une table ou un nom de champ). C'est un cas rare mais il vaut mieux être préparé.

Dans ce cas, votre variable doit être comparée à une liste de valeurs explicitement écrit dans votre script. Ceci est expliqué dans mon autre article, Ajout d'un nom de champ dans la clause ORDER BY en fonction du choix de l'utilisateur :

Malheureusement, PDO n'a pas d'espace réservé pour les identifiants (noms de table et de champ), par conséquent, un développeur doit les filtrer manuellement. Un tel filtre est souvent appelé "liste blanche" (où nous n'énumérons que les valeurs autorisées) par opposition à une "liste noire" où nous répertorions les valeurs non autorisées.

Nous devons donc lister explicitement toutes les variantes possibles dans le code PHP, puis choisir parmi elles.

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"); 
}

Exactement la même approche devrait être utilisée pour la direction,

$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 tel code, les deux $direction et $orderby les variables peuvent être placées en toute sécurité dans la requête SQL, car elles sont soit égales à l'une des variantes autorisées, soit une erreur sera générée.

La dernière chose à mentionner à propos des identifiants, ils doivent également être formatés en fonction de la syntaxe particulière de la base de données. Pour MySQL, ce devrait être backtick caractères autour de l'identifiant. Ainsi, la chaîne de requête finale pour notre commande par exemple serait

$query = "SELECT * FROM `table` ORDER BY `$orderby` $direction";