Como serializar / salvar um DOMElement em $ _SESSION?
Sou bem novo no PHP, no DOM e na implementação do PHP DOM. O que estou tentando fazer é salvar o elemento raiz doDOMDocument
em um$_SESSION
variável para que eu possa acessá-lo e modificá-lo em carregamentos de página subseqüentes.
Mas eu recebo um erro no PHP quando uso$_SESSION
para salvar o estado de DOMElement:
Aviso: DOMNode :: appendChild () [domnode.appendchild]: Não foi possível buscar DOMElement
Eu li que um objeto PHP DOMDocument não pode ser salvo para$_SESSION
nativamente. No entanto, pode ser salvo salvando a serialização do DOMDocument (por exemplo,$_SESSION['dom'] = $dom->saveXML()
).
Eu não sei se o mesmo vale para salvar umDOMElement
para um$_SESSION
variável também, mas é o que eu estava tentando. Meu motivo para querer fazer isso é usar uma classe estendida de DOMElement com uma propriedade adicional. Eu estava esperando que, salvando a raiz DOMElement em $ _SESSION que eu pudesse recuperar o elemento mais tarde e modificar essa propriedade adicional e executar um teste como, if (additionalProperty === false) {fazer alguma coisa; }. Eu também li que salvando um DOMDocument, e depois recuperando-o, todos os elementos são retornados como objetos de classes DOM nativas. Ou seja, mesmo que eu usei uma classe estendida para criar elementos, a propriedade que eu preciso subseqüentemente não estará acessível, porque a variável que contém referência ao objeto de classe estendida ficou fora do escopo - e é por isso que eu Estou tentando essa outra coisa. Eu tentei usar a classe estendida (não incluída abaixo) primeiro, mas recebi erros ... então voltei a usar um objeto DOMElement para ver se esse era o problema, mas ainda estou recebendo os mesmos erros. Aqui está o código:
<code><?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; ?> </code>
Esse código fornece os seguintes erros (dependendo se eu uso appendChild diretamente ou a linha de código comentada usando 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
Eu tenho várias perguntas. Primeiro, o que está causando esse erro e como corrigi-lo? Além disso, se o que estou tentando fazer não for possível, como posso realizar meu objetivo geral de salvar o 'estado' de uma árvore DOM enquanto estiver usando uma propriedade personalizada para cada elemento? Observe que a propriedade adicional é usada apenas no programa e não é um atributo a ser salvo no arquivo XML. Além disso, não posso simplesmente salvar o DOM de volta ao arquivo todas as vezes, porque o DOMDocument, após uma modificação, pode não ser válido de acordo com um esquema que estou usando até mais tarde quando modificações / adições adicionais foram executadas no DOMDocument. É por isso que preciso salvar um DOMDocument temporariamente inválido. Obrigado por qualquer conselho!
EDITED: Depois de tentar a solução de hakre, o código funcionou. Então, passei a tentar usar uma classe extensa de DOMElement e, como suspeitava, não funcionou. Aqui está o novo código:
<code><?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; } } ?> </code>
Isso me dá o erroUndefined property: DOMElement::$frozen
. Como eu mencionei no meu post original, depoissaveXML
eloadXML
, um elemento originalmente instanciado comFreezableDOMElement
está voltando tipoDOMElement
é por isso que ofrozen
propriedade não é reconhecida. Existe alguma maneira de contornar isso?