PHP DOM実装を使用して、DOMElement
sのサブクラスを含むカスタムドキュメントツリーを作成できましたが、非常に奇妙なことがわかりました。DOMDocumentを複製または返すと、子ノードクラスが変更されるようです。
基本例
class Section extends DOMElement
{
public function __construct($name, $value = null, $uri = null)
{
parent::__construct($name, $value, $uri);
}
}
class Paragraph extends DOMElement
{
public function __construct($name, $value = null, $uri = null)
{
parent::__construct($name, $value, $uri);
}
}
function display_doc($label, DOMDocument $doc)
{
$endl = (PHP_SAPI == "cli") ? "\n" : "<br />";
$pad = (PHP_SAPI == "cli") ? "\t" : "&nbsp;&nbsp;";
echo ($label . $endl);
$root = $doc->documentElement;
echo ($pad . "root " . get_class($root) . $endl);
echo ($pad . "first child " . get_class($root->firstChild) . $endl);
}
function test_dom($name, DOMDocument &$instance = null)
{
$doc = ($instance) ? $instance : new DOMDocument("1.0", "utf-8");
$root = $doc->appendChild($doc->createElement("root"));
$section = new Section("section");
$root->appendChild($section);
$paragraph = new Paragraph("para");
$section->appendChild($paragraph);
$clone = clone $doc;
display_doc($name . " - Inside function", $doc);
display_doc($name . " - Inside function (clone)", $clone);
return $doc;
}
$doc = test_dom("Using new instance");
display_doc("Returned doc in global scope", $doc);
$doc2 = new DOMDocument("1.0", "utf-8");
test_dom("Using global scope instance", $doc2);
display_doc("Modified doc in global scope", $doc2);
出力します
新しいインスタンスの使用-内部関数 ルートDOMElement 最初の子セクション 新しいインスタンスの使用-内部関数(クローン) ルートDOMElement 最初の子DOMElement グローバルスコープで返されたドキュメント ルートDOMElement 最初の子DOMElement グローバルスコープインスタンスの使用-内部関数 ルートDOMElement 最初の子セクション グローバルスコープインスタンスの使用-内部関数(クローン) ルートDOMElement 最初の子DOMElement グローバルスコープで変更されたドキュメント ルートDOMElement 最初の子DOMElement
ドキュメントが複製または返されると、最初の子のクラスが単純からSection
単純に変わります(参照によっても)DOMElement
- 私のPHPバージョンは5.3.10ですが、同じ動作が5.4でも発生します
- DOMDocument :: registerNodeClassを使用すると
DOMElement
、登録されたノードクラスによって変換されますが、次のサブクラスが複数あります。DOMElement
私の質問は、実際には回避策や別の解決策を見つけることではありませんが、ここで何が起こっているのか、そしてどのメカニズムによって子ノードが変換されるのかを理解したいと思います。
編集:この問題に関連するバグレポート(2歳)を見つけました:http://www.mail-archive.com/php-bugs@lists.php.net/msg134710.html。提案された回避策はうまく機能しますが、それが実際のバグなのか、DOMAPIの無効な使用なのかは不明です。