PHPのDOMDocumentを使って、日本語を含むHTMLの一部分を文字列として生成する

うまいタイトルが思い浮かばなかったのですが、

コメント
<hr>
<div>ハロー
  <p>ワールド</p>
</div>

のようなものを、PHPのDOMDocumentを使って実現する時に悩んだので、メモに残します。

もし、他に良い方法があれば教えて頂けるとありがたいです。

 

目次

 

環境

 

悩んだ点と対応

タグのないところにテキストやタグを入れる

タグに囲まれている部分にテキストを入れる場合

$dom = new DOMDocument();
$dom->appendChild($dom->createElement('div', 'ハロー'));

とすれば

<div>ハロー</div>

というHTMLが作れます。

ただ、今回は

コメント
<hr>

のように、hrタグの前にテキストを入れる必要がありました。

 
この場合、 createTextNode を使えば良さそうでした。

 
そのため、

$dom = new DOMDocument();

$comment = $dom->createTextNode('コメント');
$dom->appendChild($comment);

$dom->appendChild($dom->createElement('hr'));

とすることで、

コメント<hr>

となりました。

 

日本語を含むHTMLを文字列にする

DOMDocumentをHTMLの文字列にするには、 saveHTML() を使えば良さそうでした。
PHP: DOMDocument::saveHTML - Manual

 
しかし、

$dom = new DOMDocument();

$comment = $dom->createTextNode('コメント');
$dom->appendChild($comment);

$dom->appendChild($dom->createElement('hr'));

$div = $dom->appendChild($dom->createElement('div', 'ハロー'));

$div->appendChild($dom->createElement('p', 'ワールド'));
$dom->saveHTML();

echo $html;

のように、日本語を含むDOMDocumentに対して使ったところ

&#12467;&#12513;&#12531;&#12488;
<hr>
<div>&#12495;&#12525;&#12540;
  <p>&#12527;&#12540;&#12523;&#12489;</p>
</div>

と、日本語は数値文字参照での表現となりました。

 
この場合、 mb_convert_encoding() を使えば良さそうでした。

 

そのため、 mb_convert_encoding() を使って文字コードHTML-ENTITIES から UTF-8 へと変更するよう、

// ここまでは同じ
$div->appendChild($dom->createElement('p', 'ワールド'));

// 変更
$html = mb_convert_encoding($dom->saveHTML(), 'utf-8', 'HTML-ENTITIES');

echo $html;

としたところ、

コメント
<hr>
<div>ハロー
  <p>ワールド</p>
</div>

と、日本語のHTMLの文字列となりました。

 

ソースコード

Githubに上げました。 dom_document/create_html.php が今回のファイルです。
https://github.com/thinkAmi-sandbox/php-sample