Fatal Error: Unexpected BLOG

主に自分用の備忘録として

【PHP】DOMDocument::loadHTML()で日本語が化けるときの対処法と残った謎

ファイルから読み込んだ断片的なHTML文書をDOMDocumentクラスを使って解析しようとした時に文字化けに遭遇した。
とりあえず文字化けは回避出来たけど、原因とか根本的な解決とか謎のままなのでメモ。

以下のサイトを参考にさせて頂きました。

環境は以下

loadHTML()したドキュメントをsaveHTML()すると化ける

読み込んでいるデータも出力先もソースファイルもエンコードUTF-8
loadHTML()するデータは断片的なものなので<head>が含まれていない。(ワケあってここは制御できない)
そのあたりも関係していそう。
現象としては、HTMLエンティティがそのまま文字列として出てきちゃってる感じ?
出力をブラウザで表示しても、ファイルに保存しても日本語部分が化ける。

対処法

loadHTML()とsaveHTML()の直前でmb_convert_encoding()してあげたら化けなかった。

<?php
$stringHTML = "<p>HTMLドキュメント</p>"; //なにかしらのHTML文字列
$dom = new DOMDocument();
$dom->loadHTML(mb_convert_encoding($stringHTML, 'HTML-ENTITIES', 'utf-8'));

$out = mb_convert_encoding($dom->saveHTML(), 'utf-8', 'HTML-ENTITIES');
echo $out;

'HTML-ENTITIES'でエンコーディングするっていう発想がなかったし、見落としかもしれないけど公式にも記述は無い。

一応文字化けは回避できたけど、根本的なところが理解できていないので、忘れないようにメモ。

余談

DOMDocumentの公式マニュアル見ると、loadHTML()はスタティックにコールできるって書いてあるけど、
下の方にしれっと「コールすることは出来るけど、E_STRICT エラーが発生します。」って書いてあるので注意。