230 votes

PHP DOMDocument loadHTML ne codant pas correctement UTF-8

Je suis en train d'analyser le code HTML à l'aide de DOMDocument, mais quand je le fais, j'ai soudainement perdu mon encodage (du moins, c'est qu'il me semble).

$profile = "<div><p>various japanese characters</p></div>";
$dom = new DOMDocument();
$dom->loadHTML($profile); 

$divs = $dom->getElementsByTagName('div');

foreach ($divs as $div) {
    echo $dom->saveHTML($div);
}

Le résultat de ce code est que je reçois un tas de personnages qui ne sont pas Japonais. Cependant, si je fais:

echo $profile;

il s'affiche correctement. J'ai essayé saveHTML et saveXML, et ni l'afficher correctement. Je suis à l'aide de PHP 5.3.

Ce que je vois:

ã¤ãªãã¤å·ã·ã«ã´ã«ã¦ãã¢ã¤ã«ã©ã³ãç³»ã®å®¶åº­ã«ã9人åå¼ã®5çªç®ã¨ãã¦çã¾ãããå½¼ãå«ãã¦4人ã俳åªã«ãªã£ããç¶è¦ªã¯æ¨æã®ã»ã¼ã«ã¹ãã³ã§ãæ¯è¦ªã¯éµä¾¿å±ã®å®¢å®¤ä¿ã ã£ããé«æ ¡æ代ã¯ã­ã£ãã£ã®ã¢ã«ãã¤ãã«å¤ãã¿ãæè²è³éãåããªããã«ããªãã¯ç³»ã®é«æ ¡ã¸é²å­¦ã

Ce qui doit être montré:

イリノイ州シカゴにて、アイルランド系の家庭に、9人兄弟の5番目として生まれる。彼を含めて4人が俳優になった。父親は木材のセールスマンで、母親は郵便局の客室係だった。高校時代はキャディのアルバイトに勤しみ、教育資金を受けながらカトリック系の高校へ進学

EDIT: j'ai simplifié le code à cinq lignes de sorte que vous pouvez tester vous-même.

$profile = "<div lang=ja><p>イリノイ州シカゴにて、アイルランド系の家庭に、</p></div>";
$dom = new DOMDocument();
$dom->loadHTML($profile);
echo $dom->saveHTML();
echo $profile;

Voici le code html qui est retourné:

<div lang="ja"><p>イリノイ州シカゴã«ã¦ã€ã‚¢ã‚¤ãƒ«ãƒ©ãƒ³ãƒ‰ç³»ã®å®¶åº­ã«ã€</p></div>
<div lang="ja"><p>イリノイ州シカゴにて、アイルランド系の家庭に、</p></div>

617voto

cbuckley Points 10401

Il semble qu'il y ait un problème avec DOMDocument et loadHTML garbling le contenu UTF-8. Il existe une solution de contournement dans SmartDOMDocument qui devrait vous aider à:

 $profile="<div><p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p></div>";
$dom = new DomDocument();
$dom->loadHTML(mb_convert_encoding($profile, 'HTML-ENTITIES', 'UTF-8'));
$divs = $dom->getElementsByTagName('div');

foreach ($divs as $div) {
    echo $dom->saveHTML($div);
}
 

Une alternative consiste à ajouter une déclaration de codage XML au HTML, à condition que le document n'en contienne pas déjà une:

 $dom->loadHTML('<?xml encoding="utf-8" ?>' . $profile);
 

85voto

Greeso Points 914

Le problème, c'est avec saveHTML et saveXML, deux d'entre eux ne fonctionnent pas correctement dans Unix. Ils ne sauvent pas les caractères utf8 correctement lorsqu'ils sont utilisés dans les environnements Unix, mais ils travaillent dans Windows.

La solution est très simple:

Si vous essayez par défaut, vous obtenez le message d'erreur que vous avez décrit

$str = dom->saveHTML(); // saves incorrectly

Tout ce que vous avez à faire est d'enregistrer comme suit:

$str = $dom->saveHTML(dom->documentElement); // saves correctly

Cette ligne de code obtenez vos caractères utf8 être enregistré correctement (la solution est la même si vous utilisez saveXML).


Note

  1. Caractères anglais ne cause pas de problème lorsque vous utilisez saveHTML sans paramètres (parce que l'anglais caractères sont enregistrés que sur un seul octet caractères en utf8)

  2. Le problème se produit lorsque vous avez de caractères multi-octets (comme le Chinois, le russe, l'arabe, Heabrow, ...etc).

Je recommande la lecture de cet article: http://coding.smashingmagazine.com/2012/06/06/all-about-unicode-utf8-character-sets/. Vous comprendrez comment utf8 fonctionne et pourquoi vous avez ce problème. Il vous faudra environ 30 minutes, mais c'est du temps bien dépensé.

19voto

Hossein Points 2286

Assurez-vous que le fichier source réel est enregistré au format UTF-8 (vous pouvez même essayer les caractères de nomenclature non recommandés avec UTF-8 pour vous en assurer).

Toujours dans le cas du HTML, assurez-vous d’avoir déclaré le codage correct à l’aide des balises meta :

 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 

S'il s'agit d'un CMS (puisque vous avez marqué votre question avec Joomla), vous devrez peut-être configurer les paramètres appropriés pour le codage.

5voto

Lazaros Kosmidis Points 141

Vous devez fournir au DOMDocument une version de votre code HTML avec un en-tête qui a du sens. Tout comme HTML5.

 $profile ='<?xml version="1.0" encoding="'.$_encoding.'"?>". $html;
 

C'est peut-être une bonne idée de garder votre code HTML aussi valide que possible, afin d'éviter les problèmes lorsque vous lancerez une requête ... autour de :-) et restez à l'écart de htmlentities !!! ! C'est un gaspillage de ressources nécessaire. gardez votre code fou !!!!

-1voto

copndz Points 391

Le problème est que lorsque vous ajoutez un paramètre à la fonction DOMDocument :: saveHTML (), vous perdez le codage. Dans quelques cas, vous devrez éviter l'utilisation du paramètre et utiliser l'ancienne fonction de chaîne pour trouver ce que vous recherchez.

Je pense que la réponse précédente fonctionne pour vous, mais puisque cette solution de contournement n'a pas fonctionné pour moi, j'ajoute cette réponse pour aider les personnes qui pourraient être dans mon cas.

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