J'essaie d'analyser du HTML en utilisant DOMDocument, mais quand je le fais, je perds soudainement mon encodage (du moins c'est ainsi 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 j'obtiens un tas de caractères qui ne sont pas japonais. Cependant, si je fais:
echo $profile;
il s'affiche correctement. J'ai essayé saveHTML et saveXML, et aucun des deux ne s'affiche correctement. J'utilise 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 pour que vous puissiez le tester vous-même.
$profile = "<div lang=ja><p>イリノイ州シカゴにて、アイルランド系の家庭に、</p></div>";
$dom = new DOMDocument();
$dom->loadHTML($profile);
echo $dom->saveHTML();
echo $profile;
Voici le html qui est retourné:
<div lang="ja"><p>イリノイ州シカゴã«ã¦ã€ã‚¢ã‚¤ãƒ«ãƒ©ãƒ³ãƒ‰ç³»ã®å®¶åºã«ã€</p></div>
<div lang="ja"><p>イリノイ州シカゴにて、アイルランド系の家庭に、</p></div>
php
utf-8
character-encoding
Légèrement A.
la source
la source
Réponses:
DOMDocument::loadHTML
traitera votre chaîne comme étant ISO-8859-1, sauf indication contraire de votre part. Cela entraîne une interprétation incorrecte des chaînes UTF-8.Si votre chaîne ne contient pas de déclaration de codage XML, vous pouvez en ajouter une pour que la chaîne soit traitée comme UTF-8:
$profile = '<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>'; $dom = new DOMDocument(); $dom->loadHTML('<?xml encoding="utf-8" ?>' . $profile); echo $dom->saveHTML();
Si vous ne pouvez pas savoir si la chaîne contiendra déjà une telle déclaration, il existe une solution de contournement dans SmartDOMDocument qui devrait vous aider:
$profile = '<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>'; $dom = new DOMDocument(); $dom->loadHTML(mb_convert_encoding($profile, 'HTML-ENTITIES', 'UTF-8')); echo $dom->saveHTML();
Ce n'est pas une excellente solution de contournement, mais comme tous les caractères ne peuvent pas être représentés dans ISO-8859-1 (comme ces katana), c'est l'alternative la plus sûre.
la source
$dom->loadHTML('<?xml encoding="utf-8" ?>' . $content);
corrigé pour moi dans PHP7 (donc c'est toujours un problème) - c'est un problème vraiment ennuyeux, car j'ai défini utf8 dans le document HTML (avec<meta charset="UTF-8" />
) mais cela n'a aucun effet, il semble avoir besoin de la partie <? xml, qui est totalement peu intuitif.$dom->loadHTML(mb_convert_encoding($profile, 'HTML-ENTITIES', 'UTF-8'));
fonctionne très bien! Merci,Le problème vient de
saveHTML()
etsaveXML()
, les deux ne fonctionnent pas correctement sous Unix. Ils n'enregistrent pas correctement les caractères UTF-8 lorsqu'ils sont utilisés sous Unix, mais ils fonctionnent sous Windows.La solution de contournement est très simple:
Si vous essayez la valeur par défaut, vous obtiendrez l'erreur que vous avez décrite
$str = $dom->saveHTML(); // saves incorrectly
Tout ce que vous avez à faire est de sauvegarder comme suit:
$str = $dom->saveHTML($dom->documentElement); // saves correctly
Cette ligne de code permettra à vos caractères UTF-8 d'être enregistrés correctement. Utilisez la même solution de contournement si vous utilisez
saveXML()
.Mise à jour
Comme suggéré par " Jack M " dans la section commentaires ci-dessous, et vérifié par " Pamela " et " Marco Aurélio Deleu ", la variation suivante pourrait fonctionner dans votre cas:
Remarque
Les caractères anglais ne posent aucun problème lorsque vous utilisez
saveHTML()
sans paramètres (car les caractères anglais sont enregistrés en tant que caractères à un octet en UTF-8)Le problème se produit lorsque vous avez des caractères multi-octets (tels que chinois, russe, arabe, hébreu, ... etc.)
Je recommande de lire cet article: http://coding.smashingmagazine.com/2012/06/06/all-about-unicode-utf8-character-sets/ . Vous comprendrez comment fonctionne UTF-8 et pourquoi vous rencontrez ce problème. Cela vous prendra environ 30 minutes, mais c'est du temps bien dépensé.
la source
$str = utf8_decode($dom->saveHTML($dom->documentElement));
utf8_decode($dom->saveHTML($dom->documentElement));
l'a fait parfaitement pour moi.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 bon encodage à l'aide de
meta
balises:<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
S'il s'agit d'un CMS (comme vous avez tagué votre question avec Joomla), vous devrez peut-être configurer les paramètres appropriés pour l'encodage.
la source
<meta charset="UTF-8">
balise ne fonctionne pas avec DOMDocument.<meta charset="UTF-8">
: voir 3v4l.org/AATjhCela m'a pris du temps à comprendre, mais voici ma réponse.
Avant d'utiliser DomDocument, j'utilisais file_get_contents pour récupérer les URL, puis les traiter avec des fonctions de chaîne. Peut-être pas le meilleur moyen mais rapide. Après avoir été convaincu que Dom était tout aussi rapide, j'ai d'abord essayé ce qui suit:
$dom = new DomDocument('1.0', 'UTF-8'); if ($dom->loadHTMLFile($url) == false) { // read the url // error message } else { // process }
Cela a échoué de façon spectaculaire à préserver l'encodage UTF-8 malgré les balises méta, les paramètres php et tous les autres remèdes proposés ici et ailleurs. Voici ce qui fonctionne:
$dom = new DomDocument('1.0', 'UTF-8'); $str = file_get_contents($url); if ($dom->loadHTML(mb_convert_encoding($str, 'HTML-ENTITIES', 'UTF-8')) == false) { }
etc. Maintenant, tout va bien avec le monde. J'espère que cela t'aides.
la source
DomDocument('1.0', 'UTF-8')
. Mais dans mon cas, seul le HTML partiel est chargé.Vous pouvez préfixer une ligne imposant le
utf-8
codage, comme ceci:@$doc->loadHTML('<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $profile);
Et vous pouvez ensuite continuer avec le code que vous avez déjà, comme:
la source
Vous devez alimenter le DOMDocument une version de votre 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 html aussi valide que possible, afin de ne pas avoir de problèmes lorsque vous commencerez la requête ... autour de :-) et restez à l'écart
htmlentities
!!!! C'est un va-et-vient nécessaire qui gaspille des ressources. gardez votre code fou !!!!la source
Les travaux me conviennent:
$dom = new \DOMDocument; $dom->loadHTML(utf8_decode($html)); ... return utf8_encode( $dom->saveHTML());
la source
?
)J'utilise php 7.3.8 sur un manjaro et je travaillais avec du contenu persan. Cela a résolu mon problème:
$html = 'hi</b><p>سلام<div>の家庭に、9 ☆'; $doc = new DOMDocument('1.0', 'UTF-8'); $doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')); print $doc->saveHTML($doc->documentElement) . PHP_EOL . PHP_EOL;
la source
Utilisez-le pour un résultat correct
$dom = new DOMDocument(); $dom->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . $profile); echo $dom->saveHTML(); echo $profile;
Cette opération
mb_convert_encoding($profile, 'HTML-ENTITIES', 'UTF-8');
C'est une mauvaise façon, car des symboles spéciaux comme & lt; , & gt; peuvent être dans $ profile, et ils ne seront pas convertis deux fois après mb_convert_encoding. C'est le trou pour XSS et un HTML incorrect.
la source
La seule chose qui a fonctionné pour moi était la réponse acceptée de
$profile = '<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>'; $dom = new DOMDocument(); $dom->loadHTML('<?xml encoding="utf-8" ?>' . $profile); echo $dom->saveHTML();
POURTANT
Cela a entraîné de nouveaux problèmes, d'avoir
<?xml encoding="utf-8" ?>
dans la sortie du document.La solution pour moi était alors de faire
foreach ($doc->childNodes as $xx) { if ($xx instanceof \DOMProcessingInstruction) { $xx->parentNode->removeChild($xx); } }
Certaines solutions m'ont dit que pour supprimer l'en-
xml
tête, je devais effectuerCela n'a pas fonctionné pour moi comme pour un document partiel (par exemple un document avec deux
<p>
balises), une seule des<p>
balises était retournée.la source
Peut également encoder comme ci-dessous .... recueilli à partir de https://davidwalsh.name/domdocument-utf8-problem
$profile = '<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>'; $dom = new DOMDocument(); $dom->loadHTML(mb_convert_encoding($profile, 'HTML-ENTITIES', 'UTF-8')); echo $dom->saveHTML();
la source
Cela a fonctionné pour moi.
Dans le
php.ini
fichier, modifiez la propriété suivante.Avant:
Après:
la source
Le problème est que lorsque vous ajoutez un paramètre à une
DOMDocument::saveHTML()
fonction, vous perdez l'encodage. 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 comme 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.
la source