Obtenir un codage correct est vraiment délicat - il y a trop de couches :
- Navigateur
- Page
- PHP
- MySQL
La commande SQL "SET CHARSET utf8" de PHP garantit que le côté client (PHP) obtiendra les données en utf8, quelle que soit la manière dont elles sont stockées dans la base de données. Bien sûr, elles doivent d'abord être stockées correctement.
Définition DDL vs. données réelles
L'encodage défini pour une table/colonne ne signifie pas vraiment que les données sont dans cet encodage. Si vous avez une table définie comme utf8
mais stockés dans un encodage différent, alors MySQL les traitera comme des utf8
et vous êtes dans le pétrin. Ce qui veut dire que tu dois d'abord régler ça.
Ce qu'il faut vérifier
Vous devez vérifier dans quel codage les données circulent à chaque couche.
- Vérifiez les en-têtes HTTP, les en-têtes.
- Vérifiez ce qui est réellement envoyé dans le corps de la requête.
- N'oubliez pas que MySQL dispose d'un encodage presque partout :
- Base de données
- Tableaux
- Colonnes
- Le serveur dans son ensemble
- Client
Assurez-vous qu'il y a le bon partout.
Conversion
Si vous recevez des données dans, par exemple windows-1250
et que vous voulez stocker dans utf-8
alors utilisez ce SQL avant de stocker :
SET NAMES 'cp1250';
Si vous avez des données dans la base de données en tant que windows-1250
et que je veux récupérer utf8
utiliser :
SET CHARSET 'utf8';
Quelques notes supplémentaires :
- Ne vous fiez pas à des outils trop "intelligents" pour afficher les données. Par exemple, phpMyAdmin fait (faisait quand je l'utilisais) un encodage vraiment mauvais. Et il passe par toutes les couches, donc il est difficile de s'en rendre compte.
- De plus, Internet Explorer avait un comportement vraiment stupide consistant à "deviner" l'encodage en fonction de règles étranges.
- Utilisez des éditeurs simples où vous pouvez changer d'encodage. Je recommande MySQL Workbench.
4 votes
"SET NAMES utf8" doit être évité à cause de l'injection SQL. Voir php.net/manual/en/mysqlinfo.concepts.charset.php pour plus de détails.
3 votes
@masakielastic Je ne vois pas en quoi le fait de définir 'set names utf8' est une menace pour l'injection sql ? En utilisant l'API MySQL appropriée, où est le problème ?
3 votes
Désolé pour ma méchanceté. Voir la réponse de ircmaxell : stackoverflow.com/a/12118602/531320 Bien que "SET NAMES" n'ait aucun problème tant qu'il utilise UTF-8, la possibilité que vous utilisiez GBK ou Big5 (chinois) ou Shift_JIS (japonais) dans le futur est indéniable.