要するに、次のようなスクリプトを書いたら
<?php $html = file_get_contents('sample.html'); $html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'); $dom = new DOMDocument(); @$dom->loadHTML($html); $html = $dom->saveHTML(); file_put_contents('sample_ddtest.html', $html); exit;
sample_ddtest.htmlには、HTMLエンティティで記述された本文のHTMLができてるかなと思ったのですが、そんなことはなく普通にUTF8の人間が読めるHTMLがあったのでびっくりと。
ということは、DOMDocumentはloadとsaveの間でmb_convert_encoding($html, 'UTF-8', 'HTML-ENTITIES');が勝手に行われているわけです。
勝手にというか、おそらくですが、loadHTMLで読み込むときに自動的にmb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');してsaveHTMLするときに自動的にmb_convert_encoding($html, 'UTF-8', 'HTML-ENTITIES');しているのではないか疑惑。
しかし、loadHTML時のはやってないかもしれません。というのは、実はloadHTMLしたものの一部を別のHTMLのDOMDocumentにcloneしてInsertしたのですが、文字化けしてしまったのです。
この人は私の遭遇した文字化けに似ている感じがします。
PHP DomDocument saveHTML not encoding Japanese properly
それでは困ると思い、mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');を最初にかけたわけです。それをしたので、saveHTML()した時に戻さないとなと思ったら、なんと戻さなくてもよかったのでびっくりということです。
DOMDocumentのソースコード読めば分かるのかなぁと思いつつ、mbstringに頼るような挙動はしてないだろうし・・・・。謎です。> ソース読めよって感じですが。
更なる疑問
もしかして、更に<a>のhrefアトリビュートはURLENCODEを掛けている可能性があります。
HTML-ENTITY化したHTMLをDOMDocumentに通して戻すと、
<a href="https://support.google.com/androidmarket/developer/bin/answer.py?hl=ja&amp;answer=113466&amp;topic=2365624&amp;ctx=topic">https://support.google.com/androidmarket/developer/bin/answer.py?hl=ja&amp;answer=113466&amp;topic=2365624&amp;ctx=topic</a>
というのが、
<a href="https://support.google.com/androidmarket/developer/bin/answer.py?hl=ja%EF%BC%86%EF%BD%81%EF%BD%8D%EF%BD%90%EF%BC%9Banswer=113466%EF%BC%86%EF%BD%81%EF%BD%8D%EF%BD%90%EF%BC%9Btopic=2365624%EF%BC%86%EF%BD%81%EF%BD%8D%EF%BD%90%EF%BC%9Bctx=topic">https://support.google.com/androidmarket/developer/bin/answer.py?hl=ja&amp;answer=113466&amp;topic=2365624&amp;ctx=topic</a>
となって帰ってくるのでおかしいなぁと。
上記で注目すべきなのは、HREFでして
&amp;
が
%EF%BC%86%EF%BD%81%EF%BD%8D%EF%BD%90%EF%BC%9B(urldecodeで &amp; となる)
となってるんですね。&が&amp;なことは意図してやってるので突っ込みなしで。
URLENCODEしてるのはHREFだけじゃなくて
URLを対象にしうるものだけのようです。imgのsrcとかは変換されます。altに入れても変わらないので。