Je lis beaucoup de textes de divers flux RSS et je les insère dans ma base de données.
Bien sûr, plusieurs codages de caractères différents sont utilisés dans les flux, par exemple UTF-8 et ISO 8859-1.
Malheureusement, il y a parfois des problèmes avec les encodages des textes. Exemple:
Le "ß" dans "Fußball" devrait ressembler à ceci dans ma base de données: "Ÿ". S'il s'agit d'un "Ÿ", il s'affiche correctement.
Parfois, le "ß" dans "Fußball" ressemble à ceci dans ma base de données: "ß". Ensuite, il est affiché à tort, bien sûr.
Dans d'autres cas, le "ß" est enregistré en tant que "ß" - donc sans aucune modification. Ensuite, il est également affiché à tort.
Que puis-je faire pour éviter les cas 2 et 3?
Comment puis-je faire tout le même encodage, de préférence UTF-8? Quand dois-je utiliser utf8_encode()
, quand dois-je utiliser utf8_decode()
(c'est clair quel est l'effet mais quand dois-je utiliser les fonctions?) Et quand dois-je ne rien faire avec l'entrée?
Comment puis-je faire tout le même encodage? Peut-être avec la fonction mb_detect_encoding()
? Puis-je écrire une fonction pour cela? Mes problèmes sont donc:
- Comment savoir quel encodage le texte utilise?
- Comment le convertir en UTF-8 - quel que soit l'ancien encodage?
Une fonction comme celle-ci fonctionnerait-elle?
function correct_encoding($text) {
$current_encoding = mb_detect_encoding($text, 'auto');
$text = iconv($current_encoding, 'UTF-8', $text);
return $text;
}
Je l'ai testé, mais cela ne fonctionne pas. Qu'est ce qui ne va pas avec ça?
la source
Réponses:
Si vous appliquez
utf8_encode()
à une chaîne déjà UTF-8, elle renverra une sortie UTF-8 tronquée.J'ai créé une fonction qui traite de toutes ces questions. Ça s'appelle
Encoding::toUTF8()
.Vous n'avez pas besoin de savoir quel est l'encodage de vos chaînes. Il peut s'agir de Latin1 ( ISO 8859-1) , Windows-1252 ou UTF-8, ou la chaîne peut en avoir un mélange.
Encoding::toUTF8()
convertira tout en UTF-8.Je l'ai fait parce qu'un service me donnait un flux de données tout foiré, mélangeant UTF-8 et Latin1 dans la même chaîne.
Usage:
Télécharger:
https://github.com/neitanod/forceutf8
J'ai inclus une autre fonction,
Encoding::fixUFT8()
qui corrigera chaque chaîne UTF-8 qui semble tronquée.Usage:
Exemples:
affichera:
J'ai transformé la fonction (
forceUTF8
) en une famille de fonctions statiques sur une classe appeléeEncoding
. La nouvelle fonction estEncoding::toUTF8()
.la source
Vous devez d'abord détecter quel encodage a été utilisé. Lorsque vous analysez des flux RSS (probablement via HTTP), vous devez lire l'encodage à partir du
charset
paramètre duContent-Type
champ d'en-tête HTTP . S'il n'est pas présent, lisez le codage à partir de l'encoding
attribut de l' instruction de traitement XML . Si cela manque également, utilisez UTF-8 comme défini dans la spécification .Modifier Voici ce que je ferais probablement:
J'utiliserais cURL pour envoyer et récupérer la réponse. Cela vous permet de définir des champs d'en-tête spécifiques et de récupérer également l'en-tête de réponse. Après avoir récupéré la réponse, vous devez analyser la réponse HTTP et la diviser en en-tête et corps. L'en-tête doit alors contenir le
Content-Type
champ d'en-tête qui contient le type MIME et (espérons-le) lecharset
paramètre avec l'encodage / charset aussi. Sinon, nous analyserons le PI XML pour la présence de l'encoding
attribut et obtiendrons l'encodage à partir de là. Si cela manque également, les spécifications XML définissent l'utilisation de l'UTF-8 comme encodage.la source
charset=
etencoding=
et non pas seulement aux positions appropriées. Et troisièmement, vous ne vérifiez pas si l'encodage déclaré est accepté.La détection de l'encodage est difficile.
mb_detect_encoding
fonctionne en devinant, sur la base d'un certain nombre de candidats que vous réussissez. Dans certains codages, certaines séquences d'octets ne sont pas valides et peuvent donc distinguer différents candidats. Malheureusement, il existe de nombreux encodages, où les mêmes octets sont valides (mais différents). Dans ces cas, il n'y a aucun moyen de déterminer l'encodage; Vous pouvez implémenter votre propre logique pour faire des suppositions dans ces cas. Par exemple, les données provenant d'un site japonais peuvent être plus susceptibles d'avoir un encodage japonais.Tant que vous ne vous occupez que des langues d'Europe occidentale, les trois principaux encodages à considérer sont
utf-8
,iso-8859-1
etcp-1252
. Étant donné qu'il s'agit de valeurs par défaut pour de nombreuses plates-formes, elles sont également les plus susceptibles d'être signalées à tort. Par exemple. si les gens utilisent des encodages différents, ils seront probablement honnêtes à ce sujet, car sinon leur logiciel tomberait en panne très souvent. Par conséquent, une bonne stratégie consiste à faire confiance au fournisseur, sauf si le codage est signalé comme l'un de ces trois. Vous devriez toujours vérifier qu'il est en effet valide, en utilisantmb_check_encoding
(notez que valide n'est pas la même chose qu'être - la même entrée peut être valide pour de nombreux encodages). S'il s'agit de l'un d'entre eux, vous pouvez alors utilisermb_detect_encoding
pour les distinguer. Heureusement, c'est assez déterministe; Vous avez juste besoin d'utiliser la séquence de détection appropriée, qui estUTF-8,ISO-8859-1,WINDOWS-1252
.Une fois que vous avez détecté l'encodage, vous devez le convertir en votre représentation interne (
UTF-8
est le seul choix sensé). La fonction seutf8_encode
transformeISO-8859-1
enUTF-8
, elle ne peut donc être utilisée que pour ce type d'entrée particulier. Pour les autres encodages, utilisezmb_convert_encoding
.la source
Un très bon moyen d'implémenter une
isUTF8
fonction peut être trouvé sur php.net :la source
mb_check_encoding($string, 'UTF-8')
Ce cheatsheet répertorie quelques mises en garde courantes liées à la gestion UTF-8 en PHP: http://developer.loftdigital.com/blog/php-utf-8-cheatsheet
Cette fonction détectant les caractères multi-octets dans une chaîne peut également s'avérer utile ( source ):
la source
Un peu de tête. Vous avez dit que le "ß" devrait être affiché comme "Â" "dans votre base de données.
C'est probablement parce que vous utilisez une base de données avec un codage de caractères Latin-1 ou peut-être que votre connexion PHP-MySQL est incorrecte, c'est-à-dire que P pense que votre MySQL est configuré pour utiliser UTF-8, donc il envoie des données en UTF-8 , mais votre serveur MySQL pense que PHP envoie des données encodées en ISO 8859-1, il peut donc à nouveau essayer de coder vos données envoyées en UTF-8, provoquant ce genre de problème.
Jetez un œil à mysql_set_charset . Cela peut vous aider.
la source
Votre encodage ressemble à celui que vous avez encodé deux fois en UTF-8 ; c'est-à-dire, à partir d'un autre codage, en UTF-8, et encore en UTF-8. Comme si vous aviez ISO 8859-1, converti d'ISO 8859-1 en UTF-8 et traité la nouvelle chaîne comme ISO 8859-1 pour une autre conversion en UTF-8.
Voici un pseudocode de ce que vous avez fait:
Tu devrais essayer:
mb_detect_encoding()
ou tout ce que vous souhaitez utiliserCela suppose que dans la conversion "moyenne", vous avez utilisé ISO 8859-1. Si vous avez utilisé Windows-1252, convertissez-le en Windows-1252 (latin1). L'encodage source d'origine n'est pas important; celui que vous avez utilisé dans la deuxième conversion défectueuse est.
C'est ma conjecture sur ce qui s'est passé; il y a très peu de choses que vous auriez pu faire pour obtenir quatre octets à la place d'un octet ASCII étendu.
La langue allemande utilise également ISO 8859-2 et Windows-1250 (Latin-2).
la source
La chose intéressante à propos de
mb_detect_encoding
etmb_convert_encoding
est que l'ordre des encodages que vous proposez importe:Donc, vous voudrez peut-être utiliser un ordre spécifique lors de la spécification des encodages attendus. N'oubliez pas que ce n'est pas infaillible.
la source
if ($input_is_not_UTF8) $input_is_windows1252 = true;
. Voir aussi: html.spec.whatwg.org/multipage/…Vous devez tester le jeu de caractères en entrée car les réponses peuvent être codées avec différents encodages.
Je force tout le contenu à être envoyé en UTF-8 en effectuant la détection et la traduction en utilisant la fonction suivante:
Cette routine transformera toutes les variables PHP provenant de l'hôte distant en UTF-8.
Ou ignorez la valeur si le codage n'a pas pu être détecté ou converti.
Vous pouvez le personnaliser selon vos besoins.
Il suffit de l'invoquer avant d'utiliser les variables.
la source
L'élaboration du codage des caractères des flux RSS semble être compliquée . Même les pages Web normales omettent souvent, ou mentent, leur encodage.
Vous pouvez donc essayer d'utiliser la bonne façon de détecter l'encodage, puis revenir à une forme d'auto-détection (deviner).
la source
charset
/encoding
: décrivez l'encodage dans lequel les données sont encodées.Je sais que c'est une question plus ancienne, mais je pense qu'une réponse utile ne fait jamais de mal. J'avais des problèmes avec mon encodage entre une application de bureau, SQLite et les variables GET / POST. Certains seraient en UTF-8, certains en ASCII et, fondamentalement, tout serait foutu lorsque des personnages étrangers seraient impliqués.
Voici ma solution. Il efface votre GET / POST / REQUEST (j'ai omis les cookies, mais vous pouvez les ajouter si vous le souhaitez) à chaque chargement de page avant le traitement. Cela fonctionne bien dans un en-tête. PHP enverra des avertissements s'il ne peut pas détecter l'encodage source automatiquement, donc ces avertissements sont supprimés avec @.
la source
Je cherchais des solutions pour l'encodage depuis des siècles , et cette page est probablement la conclusion d'années de recherche! J'ai testé certaines des suggestions que vous avez mentionnées et voici mes notes:
Voici ma chaîne de test:
Je fais un INSERT pour enregistrer cette chaîne sur une base de données dans un champ défini comme
utf8_general_ci
Le jeu de caractères de ma page est UTF-8.
Si je fais un INSERT comme ça, dans ma base de données, j'ai des personnages qui viennent probablement de Mars ...
J'ai donc besoin de les convertir en un UTF-8 "sain". J'ai essayé
utf8_encode()
, mais des caractères extraterrestres envahissaient toujours ma base de données ...J'ai donc essayé d'utiliser la fonction
forceUTF8
publiée sur le numéro 8, mais dans la base de données la chaîne enregistrée ressemble à ceci:Donc, en collectant plus d'informations sur cette page et en les fusionnant avec d'autres informations sur d'autres pages, j'ai résolu mon problème avec cette solution:
Maintenant, dans ma base de données, j'ai ma chaîne avec un encodage correct.
REMARQUE: seule la note à prendre en compte est en fonction
mysql_client_encoding
! Vous devez être connecté à la base de données, car cette fonction veut un ID de ressource comme paramètre.Mais bon, je fais juste ce ré-encodage avant mon INSERT donc pour moi ce n'est pas un problème.
la source
UTF-8
encodage client pour mysql en premier lieu? N'aurait pas besoin d'une conversion manuelle de cette façonIl est simple: quand vous obtenez quelque chose qui ne UTF-8, vous devez encoder que dans UTF-8.
Ainsi, lorsque vous récupérez un certain flux qui est ISO 8859-1, analysez-le
utf8_encode
.Cependant, si vous récupérez un flux UTF-8, vous n'avez rien à faire.
la source
php.net/
mb_detect_encoding
ou
Je ne sais vraiment pas quels sont les résultats, mais je vous suggère de simplement prendre certains de vos flux avec différents encodages et d'essayer si cela
mb_detect_encoding
fonctionne ou non.update
auto est l'abréviation de "ASCII, JIS, UTF-8, EUC-JP, SJIS". il renvoie le jeu de caractères détecté, que vous pouvez utiliser pour convertir la chaîne en utf-8 avec iconv .
je ne l'ai pas testé, donc aucune garantie. et peut-être qu'il existe un moyen plus simple.
la source
@harpax qui a fonctionné pour moi. Dans mon cas, cela suffit:
la source
Après avoir trié vos scripts php, n'oubliez pas de dire à mysql quel jeu de caractères vous passez et que vous souhaitez recevoir.
Exemple: jeu de caractères set utf8
Passer des données utf8 à une table latin1 dans une session d'E / S latin1 donne ces pièges à oiseaux. Je vois cela tous les deux jours dans les magasins oscommerce. En arrière et quatrième, cela peut sembler juste. Mais phpmyadmin montrera la vérité. En disant à mysql quel jeu de caractères vous passez, il gérera la conversion des données mysql pour vous.
Comment récupérer des données mysql brouillées existantes est un autre sujet à discuter. :)
la source
Cette version est pour la langue allemande mais vous pouvez modifier les $ CHARSETS et les $ TESTCHARS
la source
Obtenez l'encodage des en-têtes et convertissez-le en utf-8.
la source
Ÿ
est Mojibakeß
. Dans votre base de données, vous pouvez avoir hexVous ne devez pas utiliser de fonctions d'encodage / décodage en PHP; à la place, vous devez configurer correctement la base de données et la connexion à celle-ci.
Si MySQL est impliqué, voir: Problème avec les caractères utf8; ce que je vois n'est pas ce que j'ai stocké
la source
Je trouve une solution ici http://deer.org.ua/2009/10/06/1/
Je pense que @ est une mauvaise décision, et apporter des modifications à la solution de deer.org.ua;
la source
La réponse la plus votée ne fonctionne pas. Voici le mien et j'espère que cela vous aidera.
la source
Lorsque vous essayez de gérer plusieurs langues comme le japonais et le coréen, vous risquez d'avoir des problèmes. mb_convert_encoding avec le paramètre 'auto' ne fonctionne pas bien. La définition de mb_detect_order ('ASCII, UTF-8, JIS, EUC-JP, SJIS, EUC-KR, UHC') n'aide pas car il détectera à tort EUC- *.
J'ai conclu que tant que les chaînes d'entrée proviennent de HTML, il devrait utiliser «charset» dans un méta-élément. J'utilise Simple HTML DOM Parser car il prend en charge le code HTML non valide.
L'extrait ci-dessous extrait l'élément de titre d'une page Web. Si vous souhaitez convertir une page entière, vous pouvez supprimer certaines lignes.
la source
J'ai eu le même problème avec phpQuery ( ISO-8859-1 au lieu d' UTF-8 ) et ce hack m'a aidé:
mb_internal_encoding('UTF-8')
,phpQuery::newDocumentHTML($html, 'utf-8')
,mbstring.internal_encoding
Et d' autres manipulations ne prennent aucun effet.la source
Essayez sans 'auto'
C'est:
au lieu de:
Plus d'informations peuvent être trouvées ici: mb_detect_encoding
la source