124 votes

SET NAMES utf8 dans MySQL ?

Je vois souvent quelque chose de similaire à ce qui suit dans les scripts PHP utilisant MySQL

query("SET NAMES utf8");   

Je n'ai encore jamais eu à le faire pour un projet et j'ai donc quelques questions de base à ce sujet.

  1. Est-ce quelque chose qui se fait uniquement avec PDO ?
  2. S'il ne s'agit pas d'un élément spécifique à l'AOP, alors à quoi cela sert-il ? Je réalise que c'est le réglage de l'encodage pour mysql mais je veux dire, je n'ai jamais eu à l'utiliser alors pourquoi voudrais-je l'utiliser ?

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.

78voto

Vinko Vrsalovic Points 116138

Il est nécessaire lorsque vous voulez envoyer au serveur des données contenant des caractères qui ne peuvent pas être représentés en ASCII pur, comme 'ñ' ou 'ö'.

Que si l'instance de MySQL n'est pas configurée pour attendre le codage UTF-8 par défaut des connexions client (beaucoup le sont, selon votre localisation et votre plateforme).

Lire http://www.joelonsoftware.com/articles/Unicode.html au cas où vous ne sauriez pas comment fonctionne Unicode.

Lire Utilisation ou non de "SET NAMES". pour voir les alternatives de SET NAMES et savoir de quoi il s'agit exactement.

3 votes

Ö" et "ñ" sont des caractères ASCII étendus. Auriez-vous toujours besoin de SET NAMES UTF8 pour eux ?

2 votes

J'ai constaté que je devais souvent ajouter utf8_decode($my_text) ; en PHP pour que les caractères UTF-8 spéciaux s'affichent correctement sur les sites Web lorsque les données sont interrogées depuis MySQL. Mes tables et mes colonnes sont paramétrées en UTF-8 dans MySQL ; cela devrait-il être nécessaire ?

1 votes

Vinko Vrsalovic : Pas nécessairement... J'avais tous mes fichiers en utf8 mais mon précédent hébergeur avait réglé le charset mysql sur latin1 et comme je n'avais pas dit à mysql que j'envoyais des caractères en utf8 (d'où le réglage des noms en utf8), il les a stockés en charset latin et tous mes caractères spéciaux (cšž slovène) avaient l'air d'avoir été écrasés par une voiture - une autre chose : lorsque vous faites une recherche dans phpmyadmin, vous ne trouverez pas de résultats, parce qu'un c est comme Å et ainsi de suite.

49voto

karim79 Points 178055

De la manuel :

SET NAMES indique quel jeu de caractères le client utilisera pour envoyer des au serveur.

De manière plus élaborée (et une fois de plus, reprise gratuitement de l'ouvrage manuel ) :

SET NAMES indique quel jeu de caractères le client utilisera pour envoyer des au serveur. Ainsi, SET NAMES 'cp1251' indique au serveur, "les futurs messages entrants de ce client seront dans le jeu de caractères cp1251". Il spécifie également le jeu de caractères que le serveur doit utiliser pour envoyer résultats au client. (Par exemple (Par exemple, il indique quel jeu de caractères de caractères à utiliser pour les valeurs des colonnes si vous utilisez une instruction SELECT).

7 votes

Je t'aime. Tu viens d'illuminer ma soirée !

38voto

Ondra Žižka Points 8262

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.

20voto

usama sulaiman Points 417

Cette requête doit être écrite avant la requête qui crée ou met à jour des données dans la base de données, cette requête ressemble à :

mysql_query("set names 'utf8'");

Notez que vous devez écrire le code que vous utilisez dans l'en-tête, par exemple si vous utilisez utf-8, vous devez l'ajouter comme ceci dans l'en-tête, sinon cela posera un problème avec Internet Explorer.

pour que votre page ressemble à ceci

<html>
    <head>
        <title>page title</title>
        <meta charset="UTF-8" />   
    </head>
    <body>
    <?php
            mysql_query("set names 'utf8'");   
            $sql = "INSERT * FROM ..... ";  
            mysql_query($sql);
    ?>    

    </body>
</html>

9 votes

Vous ne devriez pas utiliser la bibliothèque mysql de PHP, mais plutôt MySQLi ou PDO.

0 votes

Excellente réponse, merci pour l'exemple. C'est la seule réponse qui m'a aidé à visualiser ce que je devais faire et qui a résolu mon problème !

1 votes

La dernière balise devrait être </html> et non <html>.

6voto

user1783273 Points 1

Au lieu de faire cela via une requête SQL, utilisez la fonction php : mysqli::set_charset mysqli_set_charset

Note:

This is the preferred way to change the charset. Using mysqli_query() to set it (such as SET NAMES utf8) is not recommended.

Consultez la section sur les concepts de jeux de caractères MySQL pour plus d'informations.

de http://www.php.net/manual/en/mysqli.set-charset.php

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X