J'essaie d'apprendre la meilleure façon d'écrire des requêtes. Je comprends également l'importance d'être cohérent. Jusqu'à présent, j'ai utilisé au hasard des guillemets simples, des guillemets doubles et des backticks sans vraiment réfléchir.
Exemple :
$query = 'INSERT INTO table (id, col1, col2) VALUES (NULL, val1, val2)';
De plus, dans l'exemple ci-dessus, considérez que table
, col1
, val1
, etc. peuvent être des variables.
Quelle est la norme en la matière ? Que faites-vous ?
Je lis des réponses à des questions similaires depuis environ 20 minutes, mais il semble qu'il n'existe pas de réponse définitive à cette question ;
Les astérisques doivent être utilisés pour les identificateurs de table et de colonne, mais ne sont nécessaires que lorsque l'identificateur est un [mot-clé réservé MySQL] (https://dev.mysql.com/doc/refman/5.7/en/keywords.html), ou lorsque l'identificateur contient des caractères d'espacement ou des caractères en dehors d'un ensemble limité (voir ci-dessous). Il est souvent recommandé d'éviter d'utiliser des mots-clés réservés comme identificateurs de colonne ou de table lorsque cela est possible, afin d'éviter le problème de citation.
Les guillemets simples doivent être utilisés pour les valeurs de chaînes de caractères comme dans la liste VALUES()
. Les guillemets doubles sont également supportés par MySQL pour les chaînes de caractères, mais les guillemets simples sont plus largement acceptés par les autres SGBDR, c'est donc une bonne habitude d'utiliser les guillemets simples plutôt que les doubles.
MySQL s'attend également à ce que les valeurs littérales DATE
et DATETIME
soient entre guillemets simples comme des chaînes de caractères comme '2001-01-01 00:00:00'
. Consultez la documentation the Date and Time Literals pour plus de détails, en particulier les alternatives à l'utilisation du tiret -
comme délimiteur de segment dans les chaînes de date.
Dans votre exemple, je mettrais la chaîne PHP entre guillemets et j'utiliserais des guillemets simples pour les valeurs "val1" et "val2". NULL
est un mot-clé MySQL, et une (non)-valeur spéciale, et est donc non citée.
Aucun de ces identifiants de table ou de colonne n'est un mot réservé ou n'utilise de caractères nécessitant d'être cités, mais je les ai quand même cités avec des backticks (nous y reviendrons plus tard...).
Les fonctions natives du SGBDR (par exemple, NOW()
dans MySQL) ne doivent pas être citées, bien que leurs arguments soient soumis aux mêmes règles de citation des chaînes ou des identifiants déjà mentionnées.
Barre oblique inverse (`) table & ; column ───────┬_─────_┬──┬──┬──┬_┬──┬──┬──┬_┬──┬──┬──┬───────┐ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ $query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`, `updated`) VALUES (NULL, 'val1' ;, 'val2' ;, '2001-01-01' ;, NOW())" ; ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑ Mot-clé non coté ─────┴┴┴┘ │ │ │ │ │ │││││ Chaînes de caractères mono-quotées (' ;) ───────────┴────┴───┴────┘ │ │ │││││ DATE entre guillemets (' ;) ───────────────────────────┴──────────┘ │││││ Fonction sans guillemets ─────────────────────────────────────────┴┴┴┴ ┴┘
Les modèles de citation pour les variables ne changent pas, bien que si vous avez l'intention d'interpoler les variables directement dans une chaîne de caractères, elle doit être doublement citée en PHP. Assurez-vous simplement que vous avez correctement échappé les variables pour les utiliser en SQL. (Il est recommandé d'utiliser une API supportant les instructions préparées à la place, comme protection contre les injections SQL).
// Même chose avec des remplacements de variables // Ici, le nom de la table variable $table est cité à l'envers, et les variables // dans la liste VALUES sont entre guillemets. $query = "INSERT INTO `$table` (`id`, `col1`, `col2`, `date`) VALUES (NULL, '$val1', '$val2', '$date')";
Lorsque vous travaillez avec des instructions préparées, consultez la documentation pour déterminer si les espaces réservés de l'instruction doivent être cités ou non. Les API les plus populaires disponibles en PHP, PDO et MySQLi, acceptent des caractères de remplacement non cités, tout comme la plupart des API d'instructions préparées dans d'autres langages :
// PDO example with named parameters, unquoted
$query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`) VALUES (:id, :col1, :col2, :date)";
// MySQLi example with ? parameters, unquoted
$query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`) VALUES (?, ?, ?, ?)";
Selon la documentation MySQL, il n'est pas nécessaire de citer (backtick) les identificateurs utilisant le jeu de caractères suivant :
ASCII :
[0-9,a-z,A-Z$_]
(lettres latines de base, chiffres 0-9, dollar, underscore)
Vous pouvez utiliser des caractères au-delà de ce jeu comme identificateurs de table ou de colonne, y compris des espaces par exemple, mais vous devez alors les citer (backtick).
Les backticks sont généralement utilisés pour indiquer un identifiant
et aussi pour être sécurisé contre l'utilisation accidentelle des [Mots clés réservés][1].
Par exemple :
Use `database`;
Ici les backticks aideront le serveur à comprendre que le database
est en fait le nom de la base de données, et non l'identifiant de la base de données.
La même chose peut être faite pour les noms de tables et de champs. C'est une très bonne habitude si vous entourez votre identifiant de base de données avec des backticks.
Consultez cette réponse pour en savoir plus sur les backticks.
Maintenant, parlons des guillemets doubles et des guillemets simples (Michael en a déjà parlé).
Mais, pour définir une valeur, vous devez utiliser des guillemets simples ou doubles. Voyons un autre exemple.
INSERT INTO `tablename` (`id, `title`) VALUES ( NULL, title1);
Ici, j'ai délibérément oublié d'entourer le title1
de guillemets. Maintenant, le serveur va prendre le title1
comme un nom de colonne (c'est-à-dire un identifiant). Donc, pour indiquer qu'il s'agit d'une valeur, vous devez utiliser des guillemets doubles ou simples.
INSERT INTO `tablename` (`id, `title`) VALUES ( NULL, 'title1');
Maintenant, en combinaison avec PHP, les guillemets doubles et simples facilitent grandement la rédaction de vos requêtes. Voyons une version modifiée de la requête de votre question.
$query = "INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, '$val1', '$val2')";
Maintenant, en utilisant les guillemets doubles dans le PHP, vous ferez en sorte que les variables $val1
et $val2
utilisent leurs valeurs, créant ainsi une requête parfaitement valide. Comme
$val1 = "my value 1";
$val2 = "my value 2";
$query = "INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, '$val1', '$val2')";
fera que
INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, 'my value 1', 'my value 2')
Si les colonnes de la table et les valeurs sont des variables, il y a deux façons de procéder :
Avec des guillemets doubles ""
la requête complète :
$query = "INSERT INTO $table_name (id, $col1, $col2)
VALUES (NULL, '$val1', '$val2')";
Ou
$query = "INSERT INTO ".$table_name." (id, ".$col1.", ".$col2.")
VALUES (NULL, '".$val1."', '".$val2."')";
Avec des guillemets simples ''
:
$query = 'INSERT INTO '.$table_name.' (id, '.$col1.', '.$col2.')
VALUES (NULL, '.$val1.', '.$val2.')';
Utilisez les guillemets arrière ``
lorsqu'un nom de colonne/valeur est similaire à un mot-clé réservé de MySQL.
Note: Si vous désignez un nom de colonne par un nom de table, utilisez les tirets arrière comme ceci :
`table_name
.
nom_colonne`<-- Note : excluez
.` des antisèches.