【发布时间】:2012-05-11 00:09:18
【问题描述】:
我对 PHP、DOM 和 PHP DOM 实现还很陌生。我要做的是将DOMDocument 的根元素保存在$_SESSION 变量中,以便我可以访问它并在后续页面加载时对其进行修改。
但是当我使用$_SESSION 保存 DOMElement 的状态时,我在 PHP 中遇到错误:
警告:DOMNode::appendChild() [domnode.appendchild]:无法获取 DOMElement
我读到 PHP DOMDocument 对象不能以原生方式保存到 $_SESSION。但是可以通过保存 DOMDocument 的序列化来保存它(例如$_SESSION['dom'] = $dom->saveXML())。
我不知道将DOMElement 保存到$_SESSION 变量是否也是如此,但这就是我正在尝试的。我想要这样做的原因是使用 DOMElement 的扩展类和一个附加属性。我希望通过将根 DOMElement 保存在 $_SESSION 中,以后可以检索元素并修改此附加属性并执行测试,例如 if (additionalProperty === false) { do something; }。我还通过保存 DOMDocument 并稍后检索它来阅读,所有元素都作为来自本机 DOM 类的对象返回。也就是说,即使我使用扩展类来创建元素,我随后需要的属性也将无法访问,因为持有对扩展类对象的引用的变量已经超出范围——这就是为什么我'我正在尝试其他事情。我首先尝试使用扩展类(不包括在下面),但出现错误......所以我恢复使用 DOMElement 对象来查看是否是问题所在,但我仍然遇到相同的错误。代码如下:
<?php
session_start();
$rootTag = 'root';
$doc = new DOMDocument;
if (!isset($_SESSION[$rootTag])) {
$_SESSION[$rootTag] = new DOMElement($rootTag);
}
$root = $doc->appendChild($_SESSION[$rootTag]);
//$root = $doc->appendChild($doc->importNode($_SESSION[$rootTag], true));
$child = new DOMElement('child_element');
$n = $root->appendChild($child);
$ct = 0;
foreach ($root->childNodes as $ch) echo '<br/>'.$ch->tagName.' '.++$ct;
$_SESSION[$rootTag] = $doc->documentElement;
?>
此代码给出以下错误(取决于我是直接使用 appendChild 还是使用 importNode 的注释代码行):
Warning: DOMNode::appendChild() [domnode.appendchild]: Couldn't fetch DOMElement in C:\Program Files\wamp_server_2.2\www\test2.php on line 11
Warning: DOMDocument::importNode() [domdocument.importnode]: Couldn't fetch DOMElement in C:\Program Files\wamp_server_2.2\www\test2.php on line 12
我有几个问题。首先,是什么导致了这个错误,我该如何解决?另外,如果我试图做的事情是不可能的,那么我如何实现我的总体目标,即在为每个元素使用自定义属性的同时保存 DOM 树的“状态”?请注意,附加属性仅在程序中使用,而不是要保存在 XML 文件中的属性。此外,我不能每次都将 DOM 保存回文件,因为 DOMDocument 在修改后,根据我正在使用的模式可能无效,直到稍后对 DOMDocument 执行其他修改/添加。这就是为什么我需要保存一个暂时无效的 DOMDocument。感谢您的建议!
编辑: 在尝试了 hakre 的解决方案后,代码起作用了。然后我继续尝试使用 DOMElement 的扩展类,但正如我所怀疑的那样,它不起作用。这是新代码:
<?php
session_start();
//$_SESSION = array();
$rootTag = 'root';
$doc = new DOMDocument;
if (!isset($_SESSION[$rootTag])) {
$root = new FreezableDOMElement($rootTag);
$doc->appendChild($root);
} else {
$doc->loadXML($_SESSION[$rootTag]);
$root = $doc->documentElement;
}
$child = new FreezableDOMElement('child_element');
$n = $root->appendChild($child);
$ct = 0;
foreach ($root->childNodes as $ch) {
$frozen = $ch->frozen ? 'is frozen' : 'is not frozen';
echo '<br/>'.$ch->tagName.' '.++$ct.': '.$frozen;
//echo '<br/>'.$ch->tagName.' '.++$ct;
}
$_SESSION[$rootTag] = $doc->saveXML();
/**********************************************************************************
* FreezableDOMElement class
*********************************************************************************/
class FreezableDOMElement extends DOMElement {
public $frozen; // boolean value
public function __construct($name) {
parent::__construct($name);
$this->frozen = false;
}
}
?>
它给了我错误Undefined property: DOMElement::$frozen。就像我在原始帖子中提到的那样,在saveXML 和loadXML 之后,最初用FreezableDOMElement 实例化的元素返回类型DOMElement,这就是无法识别frozen 属性的原因。有没有办法解决这个问题?
【问题讨论】:
标签: php session dom serialization