decodificar - utf8_encode php ejemplo
PHP DOMDocument loadHTML no codifica UTF-8 correctamente (10)
Estoy tratando de analizar algo de HTML usando DOMDocument, pero cuando lo hago, de repente pierdo mi codificación (al menos así es como me parece).
$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);
}
El resultado de este código es que obtengo un grupo de caracteres que no son japoneses. Sin embargo, si lo hago:
echo $profile;
se muestra correctamente Intenté guardarHTML y saveXML, y tampoco se muestran correctamente. Estoy usando PHP 5.3.
Lo que veo:
ã¤ãªãã¤å·ã·ã«ã´ã«ã¦ãã¢ã¤ã«ã©ã³ãç³»ã®å®¶åºã«ã9人åå¼ã®5çªç®ã¨ãã¦çã¾ãããå½¼ãå«ãã¦4人ã俳åªã«ãªã£ããç¶è¦ªã¯æ¨æã®ã»ã¼ã«ã¹ãã³ã§ãæ¯è¦ªã¯éµä¾¿å±ã®å®¢å®¤ä¿ã ã£ããé«æ ¡æ代ã¯ãã£ãã£ã®ã¢ã«ãã¤ãã«å¤ãã¿ãæè²è³éãåããªããã«ããªãã¯ç³»ã®é«æ ¡ã¸é²å¦ã
Lo que se debe mostrar:
イリノイ州シカゴにて、アイルランド系の家庭に、9人兄弟の5番目として生まれる。彼を含めて4人が俳優になった。父親は木材のセールスマンで、母親は郵便局の客室係だった。高校時代はキャディのアルバイトに勤しみ、教育資金を受けながらカトリック系の高校へ進学
EDITAR: simplifiqué el código en cinco líneas para que pueda probarlo usted mismo.
$profile = "<div lang=ja><p>イリノイ州シカゴにて、アイルランド系の家庭に、</p></div>";
$dom = new DOMDocument();
$dom->loadHTML($profile);
echo $dom->saveHTML();
echo $profile;
Aquí está el html que se devuelve:
<div lang="ja"><p>イリノイ州シカゴã«ã¦ã€ã‚¢ã‚¤ãƒ«ãƒ©ãƒ³ãƒ‰ç³»ã®å®¶åºã«ã€</p></div>
<div lang="ja"><p>イリノイ州シカゴにて、アイルランド系の家庭に、</p></div>
Úselo para el resultado correcto
$dom = new DOMDocument();
$dom->loadHTML(''<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'' . $profile);
echo $dom->saveHTML();
echo $profile;
Esta operacion
mb_convert_encoding($profile, ''HTML-ENTITIES'', ''UTF-8'');
Es una mala forma, porque símbolos especiales como & lt; , & gt; puede estar en $ profile, y no se convertirán dos veces después de mb_convert_encoding. Es el agujero para XSS y HTML incorrecto.
Asegúrese de que el archivo fuente real se haya guardado como UTF-8 (es posible que desee probar las Caracteres BOM no recomendados con UTF-8 para asegurarse).
También en el caso de HTML, asegúrese de haber declarado la codificación correcta usando meta
:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Si se trata de un CMS (ya que ha etiquetado su pregunta con Joomla), puede que necesite configurar los ajustes apropiados para la codificación.
Debe darle a DOMDocument una versión de su HTML con un encabezado que tenga sentido. Al igual que HTML5.
$profile =''<?xml version="1.0" encoding="''.$_encoding.''"?>''. $html;
tal vez sea una buena idea mantener tu html tan válido como puedas, para que no tengas problemas cuando comiences la consulta ... alrededor :-) y mantente alejado de htmlentities
!!!! Es un recurso necesario para perder recursos. mantener tu código loco!
El problema es con saveHTML()
y saveXML()
, ambos no funcionan correctamente en Unix. No guardan caracteres UTF-8 correctamente cuando se usan en Unix, pero funcionan en Windows.
La solución es muy simple:
Si prueba el valor predeterminado, obtendrá el error que describió
$str = $dom->saveHTML(); // saves incorrectly
Todo lo que tienes que hacer es guardar de la siguiente manera:
$str = $dom->saveHTML($dom->documentElement); // saves correctly
Esta línea de código hará que sus caracteres UTF-8 se guarden correctamente (use la misma solución si está usando saveXML()
).
Nota
Los caracteres en inglés no causan ningún problema cuando utiliza
saveHTML()
sin parámetros (porque los caracteres en inglés se guardan como caracteres de un solo byte en UTF-8)El problema ocurre cuando tienes caracteres de varios bytes (como chino, ruso, árabe, hebreo, ... etc.)
Recomiendo leer este artículo: http://coding.smashingmagazine.com/2012/06/06/all-about-unicode-utf8-character-sets/ . Comprenderá cómo funciona UTF-8 y por qué tiene este problema. Le tomará unos 30 minutos, pero es un tiempo bien empleado.
El problema es que cuando agrega un parámetro a la función DOMDocument :: saveHTML (), pierde la codificación. En algunos casos, deberá evitar el uso del parámetro y utilizar la función de cadena antigua para encontrar lo que está buscando.
Creo que la respuesta anterior funciona para usted, pero dado que esta solución no funcionó para mí, estoy agregando esa respuesta para ayudar a las personas que puedan estar en mi caso.
Esto me llevó un tiempo averiguarlo, pero esta es mi respuesta.
Antes de usar DomDocument, utilizaría file_get_contents para recuperar URL y luego procesarlas con funciones de cadena. Tal vez no sea la mejor manera, pero rápido. Después de convencerme de que Dom fue tan rápido, primero intenté lo siguiente:
$dom = new DomDocument(''1.0'', ''UTF-8'');
if ($dom->loadHTMLFile($url) == false) { // read the url
// error message
}
else {
// process
}
Esto falló espectacularmente en la preservación de la codificación UTF-8 a pesar de las metaetiquetas adecuadas, la configuración de php y el resto de los remedios ofrecidos aquí y en otros lugares. Esto es lo que funciona:
$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. Ahora todo está bien con el mundo. Espero que esto ayude.
Intenta usar utf8_encode
Podría prefijar una línea que utf-8
codificación de utf-8
, como esta:
@$doc->loadHTML(''<?xml version="1.0" encoding="UTF-8"?>'' . "/n" . $profile);
Y luego puede continuar con el código que ya tiene, como:
$doc->saveXML()
Trabajos finde para mí:
$dom = new /DOMDocument;
$dom->loadHTML(utf8_decode($html));
...
return utf8_encode( $dom->saveHTML());
DOMDocument::loadHTML
tratará su cadena como si estuviera en ISO-8859-1 a menos que le indique lo contrario. Esto da como resultado que las cadenas UTF-8 se interpretan incorrectamente.
Si su cadena no contiene una declaración de codificación XML, puede anteponer una para que la cadena sea tratada como UTF-8:
$profile = ''<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>'';
$dom = new DOMDocument();
$dom->loadHTML(''<?xml encoding="utf-8" ?>'' . $profile);
echo $dom->saveHTML();
Si no puede saber si la cadena ya contiene dicha declaración, hay una solución en SmartDOMDocument que le ayudará a:
$profile = ''<p>イリノイ州シカゴにて、アイルランド系の家庭に、9</p>'';
$dom = new DOMDocument();
$dom->loadHTML(mb_convert_encoding($profile, ''HTML-ENTITIES'', ''UTF-8''));
echo $dom->saveHTML();
Esta no es una gran solución, pero dado que no todos los caracteres se pueden representar en ISO-8859-1 (como estos katana), es la alternativa más segura.