PHP: DOMDocument e UTF-8

Tags: 

Il modulo DOM di PHP contiene le funzionalità per manipolare gli oggetti dom: la classe radice è "DOMDocument", al quale può essere dato in pasto un testo in formato HTML o XML da decodificare e quindi elaborare come preferiamo.

Questa classe ha purtroppo dei noti problemi con il supporto a testi UTF-8 (e quando mai...).

Provate ad esempio questo codice, che in teoria non dovrebbe fare nulla (decodifica la stringa passata e la ricodifica senza farci nulla).

$content = '<html><body>Verrà il giorno che non ci saranno problemi di encoding</body></html>';
$document = new \DOMDocument('1.0');
$document->loadHTML($content);
$out = $document->saveHTML();

Se provate a guardare il risultato dentro $out noterete che l'accentata di "verrà" è stata "rotta" inserendo delle entity sbagliate: in pratica il nuovo html è illeggibile.

 

Come fare per risolvere la cosa? Proponiamo 2 soluzioni diverse.

 

La prima (inseriamo solo le 2 righe significative):

$document->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">' . $content);
$out = $document->saveHTML();

In pratica consiste nel dichiarare l'encoding (da notare che va usata quella forma e non <meta charset="..."> che non funziona). Va precisato che l'html cosi' creato non è formalmente corretto (i tag <meta> andrebbero inseriti dentro <head>).

Funziona tutto lo stesso, comunque volendo fare una cosa più elegante (e a prova di eventuali altre operazioni che dovete fare all'html successivamente) sarebbe meglio fare una procedura più complessa che verifica se il tag meta non c'è già, e solo in questo caso lo aggiunge nel posto giusto.

 

Una seconda soluzione che evita questo problema è la seguente:

$document->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));
$out = $document->saveHTML($document->documentElement);

Da notare che in questa soluzione è cambiata anche la riga del saveHTML: se cosi' non fosse l'html risultante sarebbe comunque corretto, ma vedremmo la a accentata sostituita con l'entità &agrave; (cosa che è formalmente corretta ma potrebbe essere un comportamento non voluto, in fondo se l'encoding dell'HTML è UTF-8 non c'è alcun bisogno di fare quella trasformazione).

 

Per avere qualche dettaglio in più si possono consultare queste pagine (da notare che almeno la seconda soluzione non è presente, se non parzialmente):

http://stackoverflow.com/questions/11309194/php-domdocument-failing-to-h...

http://stackoverflow.com/questions/8218230/php-domdocument-loadhtml-not-...

Aggiungi un commento

Scrivi la risposta in lettere (ad esempio "tre" e non "3")