Détecter l'encodage et tout faire UTF-8
je suis en train de lire de nombreux textes de différents flux RSS et de les insérer dans ma base de données.
bien sûr, il y a plusieurs codages de caractères différents utilisés dans les alimentations, par exemple UTF-8 et ISO-8859-1.
malheureusement, il y a parfois des problèmes avec l'encodage des textes. Exemple:
-
le "ß" dans "Fußball"devrait ressembler à ceci dans ma base de données: "Ÿ". Si c'est un "Ÿ", il est affiché correctement.
-
parfois, le "ß" dans "Fußball"ressemble à ceci dans ma base de données: "Ãÿâÿ". Il est affiché à tort, bien sûr.
-
dans les autres cas, le "ß" est enregistré comme un " ß " - donc sans aucun changement. Alors 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 doit-on utiliser utf8_encode()
, quand doit-on utiliser utf8_decode()
(il est clair que l'effet est mais quand dois-je utiliser les fonctions?) et quand dois-je ne rien faire avec l'entrée?
pouvez-vous m'aider et me dire comment faire tout le même encodage? Peut-être avec la fonction mb_detect_encoding()
? Je peux écrire une fonction pour ça? Donc mes problèmes sont:
- Comment savoir quel encodage utilise le texte?
- comment le convertir en UTF-8-quel que soit l'ancien encodage?
est-ce qu'une fonction comme celle-ci fonctionnerait?
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 ça ne marche pas. Quel est le problème avec elle?
24 réponses
si vous appliquez utf8_encode()
à une chaîne déjà UTF8, il retournera une sortie UTF8 brouillée.
j'ai créé une fonction qui traite de toutes ces questions. Il s'appelle Encoding::toUTF8()
.
Vous n'avez pas besoin de savoir ce que l'encodage de vos chaînes. Il peut être Latin1 (iso 8859-1), Windows-1252 ou UTF8, ou la chaîne peut avoir un mélange d'entre eux. Encoding::toUTF8()
convertira tout en UTF8.
Je l'ai fait parce qu'un service il m'a donné un flux de données tout gâché, mélangeant UTF8 et Latin1 dans la même chaîne.
Utilisation:
require_once('Encoding.php');
use \ForceUTF8\Encoding; // It's namespaced now.
$utf8_string = Encoding::toUTF8($utf8_or_latin1_or_mixed_string);
$latin1_string = Encoding::toLatin1($utf8_or_latin1_or_mixed_string);
télécharger:
https://github.com/neitanod/forceutf8
mise à jour:
j'ai inclus une autre fonction, Encoding::fixUFT8()
, qui va corriger chaque chaîne UTF8 qui semble confus.
Utilisation:
require_once('Encoding.php');
use \ForceUTF8\Encoding; // It's namespaced now.
$utf8_string = Encoding::fixUTF8($garbled_utf8_string);
exemples:
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
sortira:
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
mise à jour: j'ai transformé la fonction ( forceUTF8
) en une famille de fonctions statiques sur une classe appelée Encoding
. La nouvelle fonction est Encoding::toUTF8()
.
vous devez d'abord détecter quel encodage a été utilisé. Comme vous analysez les flux RSS (probablement via HTTP), vous devriez lire l'encodage du paramètre charset
du champ Content-Type
en-tête HTTP . S'il n'est pas présent, lire l'encodage de l'attribut encoding
de l'instruction XML processing instruction . Si cela est manquant aussi, utiliser UTF-8 comme défini dans la spécification .
modifier voici ce que je ferais probablement:
je préfère utiliser cURL d'envoyer et de chercher la réponse. Cela vous permet de définir des champs d'en-tête spécifiques et de récupérer 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 entête et corps. L'en-tête devrait alors contenir le champ d'en-tête Content-Type
qui contient le type MIME et (avec un peu de chance) le paramètre charset
avec l'encodage/charset aussi. Si ce n'est pas le cas, nous analyserons le PI XML pour la présence de l'attribut encoding
et nous obtiendrons l'encodage à partir de là. Si cela est également manquant, les spécifications XML définissent pour utiliser UTF-8 comme encodage.
$url = 'http://www.lr-online.de/storage/rss/rss/sport.xml';
$accept = array(
'type' => array('application/rss+xml', 'application/xml', 'application/rdf+xml', 'text/xml'),
'charset' => array_diff(mb_list_encodings(), array('pass', 'auto', 'wchar', 'byte2be', 'byte2le', 'byte4be', 'byte4le', 'BASE64', 'UUENCODE', 'HTML-ENTITIES', 'Quoted-Printable', '7bit', '8bit'))
);
$header = array(
'Accept: '.implode(', ', $accept['type']),
'Accept-Charset: '.implode(', ', $accept['charset']),
);
$encoding = null;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
$response = curl_exec($curl);
if (!$response) {
// error fetching the response
} else {
$offset = strpos($response, "\r\n\r\n");
$header = substr($response, 0, $offset);
if (!$header || !preg_match('/^Content-Type:\s+([^;]+)(?:;\s*charset=(.*))?/im', $header, $match)) {
// error parsing the response
} else {
if (!in_array(strtolower($match[1]), array_map('strtolower', $accept['type']))) {
// type not accepted
}
$encoding = trim($match[2], '"\'');
}
if (!$encoding) {
$body = substr($response, $offset + 4);
if (preg_match('/^<\?xml\s+version=(?:"[^"]*"|\'[^\']*\')\s+encoding=("[^"]*"|\'[^\']*\')/s', $body, $match)) {
$encoding = trim($match[1], '"\'');
}
}
if (!$encoding) {
$encoding = 'utf-8';
} else {
if (!in_array($encoding, array_map('strtolower', $accept['charset']))) {
// encoding not accepted
}
if ($encoding != 'utf-8') {
$body = mb_convert_encoding($body, 'utf-8', $encoding);
}
}
$simpleXML = simplexml_load_string($body, null, LIBXML_NOERROR);
if (!$simpleXML) {
// parse error
} else {
echo $simpleXML->asXML();
}
}
la détection de l'encodage est difficile.
mb_detect_encoding
fonctionne en devinant, basé sur un certain nombre de candidats que vous réussissez. Dans certains codages, certaines séquences d'octets sont invalides, ce qui permet de distinguer différents candidats. Malheureusement, il y a beaucoup d'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 de faire des suppositions dans ces cas. Pour exemple, les données provenant d'un site Japonais pourraient être plus susceptibles d'avoir un Japonais de codage.
aussi longtemps que vous ne vous occupez que des langues D'Europe occidentale, les trois principaux encodages à considérer sont utf-8
, iso-8859-1
et cp-1252
. Comme ce sont des valeurs par défaut pour de nombreuses plates-formes, elles sont aussi les plus susceptibles d'être signalées à tort. Par exemple. si les gens utilisent des encodages différents, ils sont susceptibles d'être francs à ce sujet, car autrement leur logiciel casserait très souvent. Par conséquent, une bonne stratégie consiste à faire confiance au fournisseur, à moins que l'encodage soit rapporté comme l'un de ces trois. Vous devez toujours vérifier qu'il est bien valide, en utilisant mb_check_encoding
(notez que valide n'est pas la même chose que étant - la même entrée peut être valide pour de nombreux encodages). Si c'est l'un d'eux, vous pouvez alors utiliser mb_detect_encoding
pour les distinguer. Heureusement que c'est assez déterministe; il Vous suffit d'utiliser le bon detect-sequence, qui est UTF-8,ISO-8859-1,WINDOWS-1252
.
une fois que vous avez détecté l'encodage, vous devez le convertir à votre représentation interne ( UTF-8
est le seul choix sain). La fonction utf8_encode
transforme ISO-8859-1
en UTF-8
, de sorte qu'elle ne peut être utilisée que pour ce type d'entrée particulier. Pour les autres encodages, utilisez mb_convert_encoding
.
ce cheatsheet liste quelques mises en garde communes liées à la manipulation de L'UTF-8 en PHP: http://developer.loftdigital.com/blog/php-utf-8-cheatsheet
cette fonction de détection de caractères multi-octets dans une chaîne de caractères pourrait également s'avérer utile ( source ):
function detectUTF8($string)
{
return preg_match('%(?:
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|\xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|\xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|[\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
|\xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
)+%xs',
$string);
}
un petit avertissement, 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 latin1 ou peut-être votre connexion php-mysql est mal réglée, c'est, php croit que votre mysql est réglé pour utiliser utf-8, donc il envoie des données comme utf8, mais votre mysql croit que php envoie des données encodées comme iso-8859-1, donc il peut Une fois de plus essayer de coder vos données envoyées comme utf-8, causant ce genre de problème.
Regardez ceci, peut vous aider: http://php.net/manual/en/function.mysql-set-charset.php
votre encodage ressemble à celui que vous avez encodé en UTF-8 deux fois ; c'est-à-dire, à partir d'un autre encodage, en UTF-8, et de nouveau en UTF-8. Comme si vous aviez iso-8859-1, converti de 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 pseudo de ce que vous avez fait:
$inputstring = getFromUser();
$utf8string = iconv($current_encoding, 'utf-8', $inputstring);
$flawedstring = iconv($current_encoding, 'utf-8', $utf8string);
, Vous devriez essayer:
- détecter l'encodage en utilisant
mb_detect_encoding()
ou ce que vous voulez utiliser - si C'est UTF-8, convertissez en iso-8859-1, et répétez l'étape 1
- enfin, convertir de nouveau en UTF-8
qui suppose que dans la conversion "moyenne" vous avez utilisé iso-8859-1. Si vous utilisez windows-1252, convertissez-le en windows-1252 (latin1). L'encodage source original n'est pas important; celui que vous avez utilisé dans la deuxième conversion défectueuse l'est.
c'est à mon avis, à ce qui s'est passé, il y a très peu d'autres choses que vous auriez pu faire pour obtenir quatre octets au lieu d'un octet ASCII étendu.
allemand langue utilise également iso-8859-2 et windows-1250 (latin2).
vous devez tester le jeu de caractères sur l'entrée car les réponses peuvent être codées avec différents encodages.
je me force à tous les contenus été envoyé en UTF-8 par faire de la détection et de la traduction à l'aide de la fonction suivante:
function fixRequestCharset()
{
$ref = array( &$_GET, &$_POST, &$_REQUEST );
foreach ( $ref as &$var )
{
foreach ( $var as $key => $val )
{
$encoding = mb_detect_encoding( $var[ $key ], mb_detect_order(), true );
if ( !$encoding ) continue;
if ( strcasecmp( $encoding, 'UTF-8' ) != 0 )
{
$encoding = iconv( $encoding, 'UTF-8', $var[ $key ] );
if ( $encoding === false ) continue;
$var[ $key ] = $encoding;
}
}
}
}
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 l'adapter à vos besoins.
il suffit de l'invoquer avant d'utiliser les variables.
la chose intéressante à propos de mb_detect_encoding
et mb_convert_encoding
est que l'ordre des encodages que vous suggérez importe:
// $input is actually UTF-8
mb_detect_encoding($input, "UTF-8", "ISO-8859-9, UTF-8");
// ISO-8859-9 (WRONG!)
mb_detect_encoding($input, "UTF-8", "UTF-8, ISO-8859-9");
// UTF-8 (OK)
donc vous pourriez vouloir utiliser un ordre spécifique lorsque vous spécifiez des encodages attendus. Enfin, gardez à l'esprit que ce n'est pas infaillible.
c'est simple: quand vous obtenez quelque chose qui n'est pas UTF8, vous devez L'encoder en utf8.
donc, quand vous allez chercher un certain flux qui est ISO-8859-1 Analyse par utf8_encode.
cependant, si vous allez chercher un aliment UTF8, vous n'avez pas besoin de faire quoi que ce soit.
travailler sur le codage de caractères des flux RSS semble être compliqué . Même les pages Web normales omettent souvent, ou mentent sur leur encodage.
Alors vous pouvez essayer d'utiliser le bon moyen de détecter l'encodage et ensuite revenir à une certaine forme d'auto-détection (deviner).
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, d'autres en ASCII, et en gros tout serait foutu en l'air quand des personnages étrangers seraient impliqués.
voici ma solution. Il scrute votre GET/POST / REQUEST (j'ai omis les cookies, mais vous pouvez les ajouter si vous le souhaitez) sur chaque page chargée avant le traitement. Il fonctionne bien dans un en-tête. PHP lancera des avertissements s'il ne peut pas détecter le codage source automatiquement, donc ces avertissements sont supprimés avec @'S.
//Convert everything in our vars to UTF-8 for playing nice with the database...
//Use some auto detection here to help us not double-encode...
//Suppress possible warnings with @'s for when encoding cannot be detected
try
{
$process = array(&$_GET, &$_POST, &$_REQUEST);
while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) {
unset($process[$key][$k]);
if (is_array($v)) {
$process[$key][@mb_convert_encoding($k,'UTF-8','auto')] = $v;
$process[] = &$process[$key][@mb_convert_encoding($k,'UTF-8','auto')];
} else {
$process[$key][@mb_convert_encoding($k,'UTF-8','auto')] = @mb_convert_encoding($v,'UTF-8','auto');
}
}
}
unset($process);
}
catch(Exception $ex){}
je vérifiais des solutions pour encoder depuis des âges, 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:
C'est ma chaîne de test:
c'est un" wròng wrìtten " string bùt inèed to pù 'sòme' special chàrs à voir thèm, convertèd par fùnctìon!! et c'est tout!
je fais un INSERT pour enregistrer cette chaîne sur un DB dans un champ qui est défini comme utf8_general_ci
Charset de ma page est UTF-8
si je fais un INSERT comme ça, dans mon DB j'ai des caractères venant probablement de Mars...
donc j'ai besoin de les transformer en un UTF-8 sain d'esprit.
J'ai essayé utf8_encode()
mais des extraterrestres ont envahi ma base de données...
donc j'ai essayé d'utiliser la fonction forceUTF8
postée sur le numéro 8 mais sur DB la chaîne de caractères sauvée ressemble à cela:
c'est un "wrÃ2ng wrÃtten" chaîne bÃ1t je nÃed à pÃ1 'sÃ2me spécial mouans rs pour voir thÃm, convertÃd par fÃ1nctÃon!! et c'est tout!
donc en recueillant plus d'infos sur cette page et en les fusionnant avec d'autres infos sur d'autres pages j'ai résolu mon problème avec cette solution:
$finallyIDidIt = mb_convert_encoding(
$string,
mysql_client_encoding($resourceID),
mb_detect_encoding($string)
);
maintenant dans ma base de données j'ai ma chaîne avec le codage correct.
NOTE:
La seule note à prendre en charge est sur la fonction mysql_client_encoding
!
Vous devez être connecté à DB parce que 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.
j'espère que cela aidera quelqu'un comme cette page m'a aidé!
merci à tous!
Mauro
php.net/ mb_detect_encoding
echo mb_detect_encoding($str, "auto");
ou
echo mb_detect_encoding($str, "UTF-8, ASCII, ISO-8859-1");
Je ne sais vraiment pas quels sont les résultats, mais je vous suggérerais de prendre quelques-uns de vos flux avec des encodages différents et d'essayer si mb_detect_encoding
fonctionne ou non.
mise à jour
auto est le diminutif de "ASCII,JIS,UTF-8,EUC-JP, SJIS". il renvoie le jeu de caractères détecté, que vous pouvez utiliser pour convertissez la chaîne en utf-8 avec iconv .
<?php
function convertToUTF8($str) {
$enc = mb_detect_encoding($str);
if ($enc && $enc != 'UTF-8') {
return iconv($enc, 'UTF-8', $str);
} else {
return $str;
}
}
?>
je n'ai pas testé, donc pas de garantie. et peut-être il ya un moyen plus simple.
@harpax qui a fonctionné pour moi. Dans mon cas, c'est suffisant:
if (isUTF8($str)) {
echo $str;
}
else
{
echo iconv("ISO-8859-1", "UTF-8//TRANSLIT", $str);
}
après avoir trié vos scripts php, n'oubliez pas de dire à mysql quel charset vous passez et que vous aimeriez recevoir.
exemple: jeu de caractères utf8
passer des données utf8 à une table latin1 dans une session I/O latin1 donne ces vilains birdfeets. Je le vois tous les deux jours dans les magasins oscommerce. Retour en arrière et quatrième il pourrait sembler juste. Mais phpmyadmin montrera la vérité. En disant à mysql quel charset vous passez, il gérera le conversion de données mysql pour vous.
comment récupérer des données MySQL brouillées existantes est un autre sujet à discuter. :)
cette version est pour la langue allemande mais vous pouvez modifier les $ CHARSETS et les $TESTCHARS
class CharsetDetector
{
private static $CHARSETS = array(
"ISO_8859-1",
"ISO_8859-15",
"CP850"
);
private static $TESTCHARS = array(
"€",
"ä",
"Ä",
"ö",
"Ö",
"ü",
"Ü",
"ß"
);
public static function convert($string)
{
return self::__iconv($string, self::getCharset($string));
}
public static function getCharset($string)
{
$normalized = self::__normalize($string);
if(!strlen($normalized))return "UTF-8";
$best = "UTF-8";
$charcountbest = 0;
foreach (self::$CHARSETS as $charset) {
$str = self::__iconv($normalized, $charset);
$charcount = 0;
$stop = mb_strlen( $str, "UTF-8");
for( $idx = 0; $idx < $stop; $idx++)
{
$char = mb_substr( $str, $idx, 1, "UTF-8");
foreach (self::$TESTCHARS as $testchar) {
if($char == $testchar)
{
$charcount++;
break;
}
}
}
if($charcount>$charcountbest)
{
$charcountbest=$charcount;
$best=$charset;
}
//echo $text."<br />";
}
return $best;
}
private static function __normalize($str)
{
$len = strlen($str);
$ret = "";
for($i = 0; $i < $len; $i++){
$c = ord($str[$i]);
if ($c > 128) {
if (($c > 247)) $ret .=$str[$i];
elseif ($c > 239) $bytes = 4;
elseif ($c > 223) $bytes = 3;
elseif ($c > 191) $bytes = 2;
else $ret .=$str[$i];
if (($i + $bytes) > $len) $ret .=$str[$i];
$ret2=$str[$i];
while ($bytes > 1) {
$i++;
$b = ord($str[$i]);
if ($b < 128 || $b > 191) {$ret .=$ret2; $ret2=""; $i+=$bytes-1;$bytes=1; break;}
else $ret2.=$str[$i];
$bytes--;
}
}
}
return $ret;
}
private static function __iconv($string, $charset)
{
return iconv ( $charset, "UTF-8" , $string );
}
}
récupérez l'encodage des en-têtes et convertissez-le en utf-8.
$post_url='http://website.domain';
/// Get headers ////////////////////////////////////////////////////////////
function get_headers_curl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
$r = curl_exec($ch);
return $r;
}
$the_header = get_headers_curl($post_url);
/// check for redirect /////////////////////////////////////////////////
if (preg_match("/Location:/i", $the_header)) {
$arr = explode('Location:', $the_header);
$location = $arr[1];
$location=explode(chr(10), $location);
$location = $location[0];
$the_header = get_headers_curl(trim($location));
}
/// Get charset /////////////////////////////////////////////////////////////////////
if (preg_match("/charset=/i", $the_header)) {
$arr = explode('charset=', $the_header);
$charset = $arr[1];
$charset=explode(chr(10), $charset);
$charset = $charset[0];
}
///////////////////////////////////////////////////////////////////////////////
// echo $charset;
if($charset && $charset!='UTF-8') { $html = iconv($charset, "UTF-8", $html); }
Ÿ
est Mojibake pour ß
. Dans votre base de données, vous pouvez avoir hex
DF if the column is "latin1",
C39F if the column is utf8 -- OR -- it is latin1, but "double-encoded"
C383C5B8 if double-encoded into a utf8 column
Vous devriez pas utiliser n'importe quel codage/décodage des fonctions en PHP; au lieu de cela, vous devez configurer la base de données et la connexion correctement.
si MySQL est impliqué, voir: problème avec les caractères utf8; ce que je vois n'est pas ce que j'ai stocké
je trouve la solution ici http://deer.org.ua/2009/10/06/1 /
class Encoding
{
/**
* http://deer.org.ua/2009/10/06/1/
* @param $string
* @return null
*/
public static function detect_encoding($string)
{
static $list = ['utf-8', 'windows-1251'];
foreach ($list as $item) {
try {
$sample = iconv($item, $item, $string);
} catch (\Exception $e) {
continue;
}
if (md5($sample) == md5($string)) {
return $item;
}
}
return null;
}
}
$content = file_get_contents($file['tmp_name']);
$encoding = Encoding::detect_encoding($content);
if ($encoding != 'utf-8') {
$result = iconv($encoding, 'utf-8', $content);
} else {
$result = $content;
}
je pense que @ est une mauvaise décision, et de faire quelques changements à la solution de deer.org.ua;
la réponse la plus votée ne fonctionne pas. Voici le mien et j'espère que ça vous aidera.
function toUTF8($raw) {
try{
return mb_convert_encoding($raw, "UTF-8", "auto");
}catch(\Exception $e){
return mb_convert_encoding($raw, "UTF-8", "GBK");
}
}
quand vous essayez de gérer plusieurs langues comme le japonais et le coréen, vous pourriez avoir des problèmes. mb_convert_encoding avec le paramètre 'auto' ne fonctionne pas bien. Définir mb_detect_order ('ASCII,UTF-8,JIS,EUC-JP,SJIS,EUC-KR,UHC') n'aide pas car il détectera EUC-* à tort.
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 parce qu'il supporte HTML invalide.
l'extrait ci-dessous extrait l'élément titre d'une page web. Si vous souhaitez convertir la page entière, alors vous pouvez supprimer quelques lignes.
<?php
require_once 'simple_html_dom.php';
echo convert_title_to_utf8(file_get_contents($argv[1])), PHP_EOL;
function convert_title_to_utf8($contents)
{
$dom = str_get_html($contents);
$title = $dom->find('title', 0);
if (empty($title)) {
return null;
}
$title = $title->plaintext;
$metas = $dom->find('meta');
$charset = 'auto';
foreach ($metas as $meta) {
if (!empty($meta->charset)) { // html5
$charset = $meta->charset;
} else if (preg_match('@charset=(.+)@', $meta->content, $match)) {
$charset = $match[1];
}
}
if (!in_array(strtolower($charset), array_map('strtolower', mb_list_encodings()))) {
$charset = 'auto';
}
return mb_convert_encoding($title, 'UTF-8', $charset);
}
j'ai eu le même problème avec phpQuery ( ISO-8859-1 au lieu de UTF-8 ) et ce hack qui m'a aidé:
$html = '<?xml version="1.0" encoding="UTF-8" ?>' . $html;
mb_internal_encoding('UTF-8')
, phpQuery::newDocumentHTML($html, 'utf-8')
, mbstring.internal_encoding
et d'autres manipulations n'ont eu aucun effet.
Essayer sans "auto",
C'est-à-dire:
mb_detect_encoding($text)
au lieu de:
mb_detect_encoding($text, 'auto')
plus d'informations peuvent être trouvées ici: mb_detect_encoding