Cette réponse met l'accent sur le php pdo bibliothèque parce que c'est tellement omniprésent.
Un bref rappel - mysql est une architecture client-serveur. Ceci est important car il n'y a pas seulement le serveur mysql où la base de données actuelle est, mais il y a aussi de différentes client mysql pilote, ce qui est la chose que les pourparlers sur le serveur mysql(ils sont des entités distinctes). Vous pourriez un peu sorta dire le client mysql et pdo sont mélangées.
Lorsque vous utilisez set names utf8
, vous émettez une requête sql standard de mysql. Alors que la requête sql ne passer par pdo, et ensuite à travers la bibliothèque cliente mysql, et puis, finalement, il atteint le serveur mysql, SEUL le serveur mysql analyse et interprète la requête sql. Ceci est important parce que le serveur mysql ne pas envoyer de message à pdo ou le client mysql laisser connaître le jeu de caractères et encodage a changé, et donc, pdo est totalement ignorant du fait qu'il s'est passé.
Il est important de ne pas effectuer cette opération car le client de la bibliothèque ne peut pas gérer correctement les chaînes si elle n'est pas au courant de la jeu de caractères. La plupart des opérations courantes fonctionnera correctement sans que le client de connaître le jeu de caractères correct, mais qui ne l'est l'échappement de la chaîne, tels que PDO::quote. Vous pouvez penser que vous n'avez pas besoin de s'inquiéter à propos de ce manuel primitive de la chaîne d'échapper, parce que vous utilisez déclarations préparées à l'avance, mais la vérité est que la grande majorité des pdo:mysql les utilisateurs sans le savoir l'utilisation des émules déclarations préparées à l'avance , car c'est le paramètre par défaut pour la pdo:pilote mysql pour un temps très long maintenant. Un émulé instruction préparée, ne pas utiliser de vrais natif mysql préparé des déclarations fournies par l'api mysql; au lieu de cela, php ne l'équivalent de l'appel d' PDO::quote()
sur tous vos valeurs, et str_replacing avec tous vos espaces réservés à la cité des valeurs pour vous.
Puisque vous ne pouvez pas échapper correctement une chaîne de caractères, sauf si vous savez le jeu de caractères que vous utilisez, ces émulé préparées sont vulnérables à l'injection sql, si vous avez modifié à certains jeux de caractères par nom de l'ensemble. Indépendamment de la question de l'injection sql, vous pouvez toujours briser vos chaînes si vous utilisez un échapper régime destiné à un jeu de caractères différent.
Pour le pilote pdo mysql, vous pouvez spécifier le jeu de caractères lorsque vous vous connectez, en le précisant dans la DSN. La bibliothèque client sera informé de la nature si vous faites cela.
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8';
Mais une mauvaise échappement de la chaîne n'est pas le seul problème. Par exemple, vous pouvez également avoir des problèmes avec l'utilisation de PDO::bindColumn parce que les noms de colonnes sont spécifiées comme des chaînes de caractères, et de nouveau le codage des questions. Un exemple pourrait être un nom de colonne nommée ütube
(notez le tréma), et vous passez de l' latin
de utf8
jeu par le biais des noms, et puis vous essayez d' $stmt->bindColumn('ütube', $var);
avec ütube
être encodés en utf-8 en chaîne, car votre fichier php est encodés en utf-8. Elle ne fonctionne pas, vous devrez encoder la chaîne comme un latin1 variante... et maintenant, vous avez toutes sortes de folie.