はじめに
PHPのDOM拡張には、XMLやHTMLをオブジェクトとして扱うためのDOMDocumentクラスがあります。その中でsaveHTML()メソッドは、内部のドキュメントをHTML文字列として出力できる便利な機能です。
しかし問題集では「XMLのタグがHTMLに存在しない場合、エラーになる」と書かれていました。これは本当なのでしょうか?実際の挙動を確認してみましょう。
🔍 問題文の内容
問題集では次のような記述がありました。
DOMDocument::saveHTML()で、内部のドキュメントをHTML形式の文字列として出力することができる。
しかし、内部のエレメント(タグ)がHTMLにないXML固有の情報の場合は、HTMLとして出力できないため、エラーとなる。
そして、以下のコード例が提示されています。
<?php
declare(strict_types=1);
error_reporting(-1);
$xml = <<<'XML'
<?xml version="1.0" encoding="UTF-8" ?>
<books>
<book>
<title>PHP8技術者認定初級試験公式問題集</title>
<author>野田貴子</author>
</book>
<book>
<title>PHP8技術者認定上級試験公式問題集</title>
<author>古圧道明</author>
</book>
</books>
XML;
$xobj = new DOMDocument();
$xobj->loadXML($xml);
echo $xobj->saveHTML();🧩 結果はどうなるのか?
実際にPHP8.0.0で実行してみると──
<books>
<book>
<title>PHP8技術者認定初級試験公式問題集</title>
<author>野田貴子</author>
</book>
<book>
<title>PHP8技術者認定上級試験公式問題集</title>
<author>古圧道明</author>
</book>
</books>ご覧の通り、エラーは一切発生せず正常に出力されます。<books> や <book> などHTMLに存在しないタグであっても、DOM構造を維持したままHTML形式として変換されています。
⚙️ 挙動の仕組み
saveHTML()は「HTMLとして出力する」ことを目的としていますが、内部的には「XMLノードをHTML的に整形して文字列化」しているだけです。
HTMLで未定義のタグが含まれていても、DOM構造が正しい限り、単に未知のタグとして出力されるだけでエラーにはなりません。
⚠️ 本当にFatal errorになるケース
「Fatal error」になるのは、次のような場合です:
loadXML()でドキュメントを読み込んでいない状態でsaveHTML()を呼んだ場合$node引数に別のDOMDocument由来のノードを渡した場合- 内部的に壊れたDOM構造を扱おうとした場合
つまり、「XMLタグがHTMLに存在しない」だけではエラーにはなりません。
🧠 図解:DOMDocumentとsaveHTMLの関係
┌──────────────────────────────────────┐
│ DOMDocument │
│ ├─ loadXML() ← XML文字列をDOMに変換 │
│ └─ saveHTML() → HTML形式で出力 │
└──────────────────────────────────────┘
↓
XMLタグがHTMLに存在しなくても…
→ そのまま未知のタグとしてHTML出力される!✅ まとめ
| 項目 | 内容 |
|---|---|
| メソッド | DOMDocument::saveHTML() |
| 機能 | DOMをHTML文字列として出力 |
| XMLタグがあっても動作する? | ✅ 正常に出力される |
| Fatal errorになる? | ❌ ならない |
| 試験での正しい答え | 「誤り」 |
📘 補足メモ:
もし本当にHTML構文を保証したい場合は、saveHTML()ではなくsaveXML()を使うのが適切です。
XML文書をそのまま扱いたい場合は、saveHTML()で無理に出力しないようにしましょう。
