web-dev-qa-db-fra.com

Caractères étranges dans le texte de la base de données: Ã, Ã, ¢, â ‚€,

Je ne sais pas quand cela s'est produit pour la première fois.

J'ai un nouveau site Web affilié de livraison directe et je reçois une copie exportée du catalogue de produits du grossiste. Je formate et importe ceci dans Prestashop 1.4.4.

La partie frontale du site Web contient des combinaisons de caractères étranges à l'intérieur du texte du produit: Ã, Ã, ¢, â ‚etc. Ils apparaissent à la place des caractères communs comme, -: etc.

Ces caractères sont présents dans environ 40% des tables de base de données, et pas seulement dans les tables spécifiques au produit comme ps_product_lang.

n autre fil de site Web dit ce même problème se produit lorsque la chaîne de connexion à la base de données utilise un type de codage de caractères incorrect .

Dans /config/setting.inc, aucune chaîne de codage de caractères n'est mentionnée, juste le moteur MySQL, qui est défini sur InnoDB, qui correspond à ce que je vois dans PHPMyAdmin.

J'ai exporté ps_product_lang, remplacé toutes les instances de ces caractères par des caractères corrects, enregistré le fichier CSV au format UTF-8 et les réimporté à l'aide de PHPMyAdmin, en spécifiant UTF-8 comme langue.

Cependant, après avoir effectué une nouvelle recherche dans PHPMyAdmin, j'ai maintenant environ 10 fois plus d'instances de ces mauvais caractères dans ps_product_lang qu'au départ.

Si le problème est aussi simple que de spécifier l'attribut de langue correct dans la chaîne de connexion à la base de données, où/comment puis-je le définir et à quoi?

Par ailleurs, j'ai essayé d'exécuter cette commande dans PHPMyAdmin mentionné dans ce fil , mais le problème persiste:

SET NAMES utf8

[~ # ~] mise à jour [~ # ~] : PHPMyAdmin dit:

Jeu de caractères MySQL: UTF-8 Unicode (utf8)

C'est le même jeu de caractères que j'ai utilisé dans le dernier fichier d'importation, ce qui a provoqué plus de corruptions de caractères. UTF-8 a été spécifié comme jeu de caractères du fichier d'importation lors du processus d'importation.

MISE À JOUR2

Voici un exemple:

les gens vivent véritablement sans attaches…. la toile.

MISE À JOUR3

J'ai exécuté une commande SQL dans PHPMyAdmin pour afficher les jeux de caractères:

  • character_set_client utf8
  • character_set_connection utf8
  • character_set_database latin1
  • caractère_set_filesystem binaire
  • character_set_results utf8
  • character_set_server latin1
  • character_set_system utf8

Donc, peut-être que ma base de données doit être convertie (ou supprimée et recréée) en UTF-8. Cela pourrait-il poser un problème si le serveur MySQL est latin1?

MySQL peut-il gérer la traduction du contenu de service en UTF8 mais le stocker en latin1? Je ne pense pas que ce soit possible, car UTF8 est un sur-ensemble de latin1. Mon support d'hébergement Web n'a pas répondu en 48 heures. Ça pourrait être trop dur pour eux.

25
Steve

Si le jeu de caractères des tables est le même que son contenu, essayez d'utiliser mysql_set_charset('UTF8', $link_identifier) . Notez que MySQL utilise UTF8 pour spécifier le codage UTF-8 au lieu de UTF-8 qui est plus courant.

Vérifiez mon autre réponse sur une question similaire aussi.

17
AlexV

C'est sûrement un problème d'encodage. Vous avez un encodage différent dans votre base de données et dans votre site Web et c'est la cause du problème. De plus, si vous avez exécuté cette commande, vous devez modifier les enregistrements qui se trouvent déjà dans vos tables pour convertir ces caractères en UTF-8.

Mise à jour : Sur la base de votre dernier commentaire, le cœur du problème est que vous avez une base de données et une source de données (le fichier CSV) qui utilisent un encodage différent . Par conséquent, vous pouvez convertir votre base de données en UTF-8 ou, au moins, lorsque vous obtenez les données qui sont dans le CSV, vous devez les convertir d'UTF-8 en latin1.

Vous pouvez effectuer la conversion en suivant ces articles:

5
Aurelio De Rosa

Appliquez ces deux choses.

  1. Vous devez définir le jeu de caractères de votre base de données sur utf8.

  2. Vous devez appeler la mysql_set_charset('utf8') dans le fichier où vous avez établi la connexion avec la base de données et juste après la sélection de la base de données comme mysql_select_db Utilisez le mysql_set_charset. Cela vous permettra d'ajouter et de récupérer des données correctement dans n'importe quelle langue.

2
Haisum Usman

Cela semble être un problème de codage UTF-8 qui peut avoir été provoqué par un double codage UTF8 du contenu du fichier de base de données.

Cette situation peut se produire en raison de facteurs tels que le jeu de caractères sélectionné ou non (par exemple lorsqu'un fichier de sauvegarde de base de données a été créé) et le format de fichier et le fichier de base de données d'encodage ont été enregistrés avec.

J'ai vu ces étranges caractères UTF-8 dans le scénario suivant (la description n'est peut-être pas tout à fait exacte car je n'ai plus accès à la base de données en question):

  • Si je me souviens bien, la base de données et les tables avaient un classement "uft8_general_ci".
  • La sauvegarde est faite de la base de données.
  • Le fichier de sauvegarde est ouvert sous Windows au format de fichier UNIX et avec le codage ANSI.
  • La base de données est restaurée sur un nouveau serveur MySQL en copiant-collant le contenu du fichier de sauvegarde de la base de données dans phpMyAdmin.

Examen du contenu du fichier:

  • L'ouverture du fichier de sauvegarde SQL dans un éditeur de texte montre que le fichier de sauvegarde SQL a des caractères étranges tels que "sà¥". Sur une note latérale, vous pouvez obtenir des résultats différents si vous ouvrez le même fichier dans un autre éditeur. J'utilise TextPad ici mais l'ouverture du même fichier dans SublimeText a dit "sà ¥" parce que SublimeText a correctement encodé le fichier UTF8 - encore, c'est un peu déroutant lorsque vous essayez de résoudre le problème dans PHP parce que vous ne voyez pas les bonnes données dans SublimeText au premier abord. Quoi qu'il en soit, cela peut être résolu en prenant note de l'encodage utilisé par votre éditeur de texte lors de la présentation du contenu du fichier.
  • Les caractères étranges sont des caractères UTF-8 à double encodage, donc dans mon cas, la première partie "Ã" est égale à "Ã" et " ¥" = "¥" (c'est mon premier "encodage"). Les caractères "à ¥" sont égaux au caractère UTF-8 pour "å" (c'est mon deuxième encodage).

Donc, le problème est que "faux" (UTF8 encodé deux fois) utf-8 doit être reconverti en "correct" utf-8 (seulement encodé UTF8 une fois).

Essayer de résoudre ce problème dans PHP s'avère un peu difficile:

utf8_decode () n'est pas en mesure de traiter les caractères.

// Fails silently (as in - nothing is output)
$str = "så";

$str = utf8_decode($str);
printf("\n%s", $str);

$str = utf8_decode($str);
printf("\n%s", $str);

iconv () échoue avec "Remarque: iconv (): Détection d'un caractère illégal dans la chaîne d'entrée".

echo iconv("UTF-8", "ISO-8859-1", "så");

Une autre solution fine et possible échoue silencieusement aussi dans ce scénario

$str = "så";
echo html_entity_decode(htmlentities($str, ENT_QUOTES, 'UTF-8'), ENT_QUOTES , 'ISO-8859-15');

mb_convert_encoding () en silence: #

$str = "så";
echo mb_convert_encoding($str, 'ISO-8859-15', 'UTF-8');
// (No output)

Essayer de corriger l'encodage dans MySQL en conversion du jeu de caractères et du classement de la base de données MySQL en UTF-8 a échoué:

ALTER DATABASE myDatabase CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE myTable CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

Je vois deux façons de résoudre ce problème.

La première consiste à effectuer une sauvegarde avec un codage correct (le codage doit correspondre au codage réel de la base de données et de la table). Vous pouvez vérifier l'encodage en ouvrant simplement le fichier SQL résultant dans un éditeur de texte.

L'autre consiste à remplacer les caractères codés en double UTF8 par des caractères codés en UTF8 unique. Cela peut être fait manuellement dans un éditeur de texte. Pour vous aider dans ce processus, vous pouvez sélectionner manuellement des caractères incorrects dans Try TF-8 Encoding Debugging Chart (il peut s'agir de remplacer 5 à 10 erreurs).

Enfin, un script peut aider au processus:

    $str = "så";
    // The two arrays can also be generated by double-encoding values in the first array and single-encoding values in the second array.
    $str = str_replace(["Ã","Â¥"], ["Ã","¥"], $str); 
    $str = utf8_decode($str);
    echo $str;
    // Output: "så" (correct)
2
Kristoffer Bohmann

J'ai rencontré aujourd'hui un problème assez similaire: mysqldump a vidé ma base utf-8 encodant les caractères diacritiques utf-8 en deux caractères latin1, bien que le fichier lui-même soit un utf8 normal.

Par exemple: "é" a été codé en deux caractères "Ã ©". Ces deux caractères correspondent au codage utf8 à deux octets de la lettre mais il doit être interprété comme un seul caractère.

Pour résoudre le problème et importer correctement la base de données sur un autre serveur, j'ai dû convertir le fichier à l'aide de ftfy (signifie "Fixes Text For You). ( https://github.com/LuminosoInsight/python-ftfy ) python. La bibliothèque fait exactement ce que j'attends: transformer un utf-8 mal encodé en utf-8 correctement encodé.

Par exemple: Cette combinaison latin1 "Ã ©" est transformée en "é".

ftfy est livré avec un script de ligne de commande mais il transforme le fichier afin qu'il ne puisse pas être réimporté dans mysql.

J'ai écrit un script python3 pour faire l'affaire:

#!/usr/bin/python3
# coding: utf-8

import ftfy

# Set input_file
input_file = open('mysql.utf8.bad.dump', 'r', encoding="utf-8")
# Set output file
output_file = open ('mysql.utf8.good.dump', 'w')

# Create fixed output stream
stream = ftfy.fix_file(
    input_file,
    encoding=None,
    fix_entities='auto', 
    remove_terminal_escapes=False, 
    fix_encoding=True, 
    fix_latin_ligatures=False, 
    fix_character_width=False, 
    uncurl_quotes=False, 
    fix_line_breaks=False, 
    fix_surrogates=False, 
    remove_control_chars=False, 
    remove_bom=False, 
    normalization='NFC'
)

# Save stream to output file
stream_iterator = iter(stream)
while stream_iterator:
    try:
        line = next(stream_iterator)
        output_file.write(line)
    except StopIteration:
        break
1
Pielo

L'erreur est généralement introduite lors de la création de CSV. Essayez d'utiliser Linux pour enregistrer le CSV en tant que TextCSV. Libre Office dans Ubuntu peut appliquer le codage en UTF-8, a fonctionné pour moi. J'ai perdu beaucoup de temps à essayer cela sur Mac OS. Linux est la clé. J'ai testé sur Ubuntu.

Bonne chance

1
Achin Kumar