new loadhtml ejemplo php utf-8 domdocument

loadhtml - php domdocument



PHP DomDocument no puede manejar caracteres utf-8(☆) (3)

Hay una solución más rápida para eso, después de cargar su documento html en DOMDocument, usted acaba de configurar (o mejor dicho reiniciar) la codificación original. Aquí hay un código de muestra:

$dom = new DOMDocument(); $dom->loadHTML(''<?xml encoding="UTF-8">'' . $html); foreach ($dom->childNodes as $item) if ($item->nodeType == XML_PI_NODE) $dom->removeChild($item); $dom->encoding = ''UTF-8''; // reset original encoding

El servidor web está publicando respuestas con codificación utf-8, todos los archivos se guardan con codificación utf-8, y todo lo que sé de la configuración se ha establecido en codificación utf-8.

Aquí hay un programa rápido para probar si el resultado funciona:

<?php $html = <<<HTML <!doctype html> <html> <head> <meta charset="utf-8"> <title>Test!</title> </head> <body> <h1>☆ Hello ☆ World ☆</h1> </body> </html> HTML; $dom = new DomDocument("1.0", "utf-8"); $dom->loadHTML($html); header("Content-Type: text/html; charset=utf-8"); echo($dom->saveHTML());

El resultado del programa es:

<!DOCTYPE html> <html><head><meta charset="utf-8"><title>Test!</title></head><body> <h1>&acirc;&#152;&#134; Hello &acirc;&#152;&#134; World &acirc;&#152;&#134;</h1> </body></html>

Que se representa como:

â~ † Hola â~ † Mundo â~ †

¿Qué podría estar haciendo mal? ¿Cuánto más específico debo ser para decirle al DomDocument que maneje correctamente el utf-8?


DOMDocument::loadHTML() espera una cadena HTML.

HTML utiliza la codificación ISO-8859-1 (alfabeto latino ISO n. ° 1) por defecto según sus especificaciones. Eso es más largo, ver 6.1. El conjunto de caracteres del documento HTML . En realidad, esa es más la compatibilidad predeterminada para Windows-1252 en los navegadores web comunes.

Vuelvo tan lejos porque el DOMDocument de PHP está basado en libxml y eso trae el HTMLparser que está diseñado para HTML 4.0.

Diría que es seguro asumir entonces que puedes cargar una cadena codificada ISO-8859-1 .

Su cadena está UTF-8 . Convierta todos los caracteres superiores a 127 / h7F en Entidades HTML y estará bien. Si no quieres hacerlo tuyo, eso es lo que hace mb_convert_encoding con la codificación de destino HTML-ENTITIES mb_convert_encoding :

  • Aquellos personajes que tienen entidades nombradas obtendrán la entidad nombrada. € -> &euro;
  • Los otros obtienen su entidad numérica (decimal), por ejemplo, ☆ -> &#9734;

El siguiente es un ejemplo de código que hace que el progreso sea un poco más visible mediante el uso de una función de devolución de llamada:

$html = preg_replace_callback(''/[/x{80}-/x{10FFFF}]/u'', function($match) { list($utf8) = $match; $entity = mb_convert_encoding($utf8, ''HTML-ENTITIES'', ''UTF-8''); printf("%s -> %s/n", $utf8, $entity); return $entity; }, $html);

Estas salidas ejemplares para su cadena:

☆ -> &#9734; ☆ -> &#9734; ☆ -> &#9734;

De todos modos, eso es solo para profundizar en su cadena. Desea que se convierta en una loadHTML codificación que loadHTML puede manejar. Eso se puede hacer convirtiendo todo fuera de US-ASCII en Entidades HTML:

$us_ascii = mb_convert_encoding($utf_8, ''HTML-ENTITIES'', ''UTF-8'');

Tenga cuidado de que su entrada esté codificada en UTF-8. Si incluso ha mezclado codificaciones (eso puede suceder con algunas entradas) mb_convert_encoding solo puede manejar una codificación por cadena. Ya expliqué anteriormente cómo hacer reemplazos de cadenas más específicamente con la ayuda de expresiones regulares, así que dejo más detalles por el momento.

La otra alternativa es insinuar la codificación. Esto se puede hacer en su caso modificando el documento y agregando un

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

que es un tipo de contenido que especifica un juego de caracteres. Esa también es la mejor práctica para las cadenas de HTML que no están disponibles a través de un servidor web (por ejemplo, guardadas en el disco o dentro de una cadena como en su ejemplo). El servidor web normalmente establece eso como el encabezado de respuesta.

Si no le importan las advertencias mal colocadas, puede agregarlas al frente de la cadena:

$dom = new DomDocument(); $dom->loadHTML(''<meta http-equiv="content-type" content="text/html; charset=utf-8">''.$html);

Según las especificaciones HTML 2.0, los elementos que solo pueden aparecer en la sección <head> de un documento se colocarán automáticamente allí. Esto es lo que sucede aquí también. La salida (bonita impresión):

<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta charset="utf-8"> <title>Test!</title> </head> <body> <h1>☆ Hello ☆ World ☆</h1> </body> </html>


<?php header("Content-type: text/html; charset=utf-8"); $html = <<<HTML <!doctype html> <html> <head> <meta charset="utf-8"> <title>Test!</title> </head> <body> <h1>☆ Hello ☆ World ☆</h1> </body> </html> HTML; $html = mb_convert_encoding($html, ''HTML-ENTITIES'', "UTF-8"); $dom = new DomDocument("1.0", "utf-8"); $dom->loadHTML($html); header("Content-Type: text/html; charset=utf-8"); echo($dom->saveHTML());

Salida:

<!DOCTYPE html> <html><head><meta charset="utf-8"><title>Test!</title></head><body> <h1>&#9734; Hello &#9734; World &#9734;</h1> </body></html>