Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7873625
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T02:34:20+00:00 2026-06-03T02:34:20+00:00

I’m pretty new to PHP, DOM, and the PHP DOM implementation. What I’m trying

  • 0

I’m pretty new to PHP, DOM, and the PHP DOM implementation. What I’m trying to do is save the root element of the DOMDocument in a $_SESSION variable so I can access it and modify it on subsequent page loads.

But I get an error in PHP when using $_SESSION to save state of DOMElement:

Warning: DOMNode::appendChild() [domnode.appendchild]: Couldn’t fetch DOMElement

I have read that a PHP DOMDocument object cannot be saved to $_SESSION natively. However it can be saved by saving the serialization of the DOMDocument (e.g. $_SESSION['dom'] = $dom->saveXML()).

I don’t know if the same holds true for saving a DOMElement to a $_SESSION variable as well, but that’s what I was trying. My reason for wanting to do this is to use an extended class of DOMElement with one additional property. I was hoping that by saving the root DOMElement in $_SESSION that I could later retrieve the element and modify this additional property and perform a test like, if (additionalProperty === false) { do something; }. I’ve also read that by saving a DOMDocument, and later retrieving it, all elements are returned as objects from native DOM classes. That is to say, even if I used an extended class to create elements, the property that I subsequently need will not be accessible, because the variable holding reference to the extended-class object has gone out of scope–which is why I’m trying this other thing. I tried using the extended class (not included below) first, but got errors…so I reverted to using a DOMElement object to see if that was the problem, but I’m still getting the same errors. Here’s the 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;
?>

This code gives the following errors (depending on whether I use appendChild directly or the commented line of code using 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

I have several questions. First, what is causing this error and how do I fix it? Also, if what I’m trying to do isn’t possible, then how can I accomplish my general objective of saving the ‘state’ of a DOM tree while using a custom property for each element? Note that the additional property is only used in the program and is not an attribute to be saved in the XML file. Also, I can’t just save the DOM back to file each time, because the DOMDocument, after a modification, may not be valid according to a schema I’m using until later when additional modificaitons/additions have been performed to the DOMDocument. That’s why I need to save a temporarily invalid DOMDocument. Thanks for any advice!

EDITED:
After trying hakre’s solution, the code worked. Then I moved on to trying to use an extended class of DOMElement, and, as I suspected, it did not work. Here’s the new 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;
    }
}
?>

It gives me the error Undefined property: DOMElement::$frozen. Like I mentioned in my original post, after saveXML and loadXML, an element originally instantiated with FreezableDOMElement is returning type DOMElement which is why the frozen property is not recognized. Is there any way around this?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T02:34:21+00:00Added an answer on June 3, 2026 at 2:34 am

    You can not store a DOMElement object inside $_SESSION. It will work at first, but with the next request, it will be unset because it can not be serialized.

    That’s the same like for DOMDocument as you write about in your question.

    Store it as XML instead or encapsulate the serialization mechanism.

    You are basically facing three problems here:

    • Serialize the DOMDocument (you do this to)
    • Serialize the FreezableDOMElement (you do this to)
    • Keep the private member FreezableDOMElement::$frozen with the document.

    As written, serialization is not available out of the box. Additionally, DOMDocument does not persist your FreezableDOMElement even w/o serialization. The following example demonstrates that the instance is not automatically kept, the default value FALSE is returned (Demo):

    class FreezableDOMElement extends DOMElement
    {
        private $frozen = FALSE;
    
        public function getFrozen()
        {
            return $this->frozen;
        }
    
        public function setFrozen($frozen)
        {
            $this->frozen = (bool)$frozen;
        }
    }
    
    class FreezableDOMDocument extends DOMDocument
    {
        public function __construct()
        {
            parent::__construct();
            $this->registerNodeClass('DOMElement', 'FreezableDOMElement');
        }
    }
    
    $doc = new FreezableDOMDocument();
    $doc->loadXML('<root><child></child></root>');
    
    # own objects do not persist
    $doc->documentElement->setFrozen(TRUE);
    printf("Element is frozen (should): %d\n", $doc->documentElement->getFrozen()); # it is not (0)
    

    As PHP does not so far support setUserData (DOM Level 3), one way could be to store the additional information inside a namespaced attribute with the element. This can also be serialized by creating the XML string when serializing the object and loading it when unserializing (see Serializable). This then solves all three problems (Demo):

    class FreezableDOMElement extends DOMElement
    {
        public function getFrozen()
        {
            return $this->getFrozenAttribute()->nodeValue === 'YES';
        }
    
        public function setFrozen($frozen)
        {
            $this->getFrozenAttribute()->nodeValue = $frozen ? 'YES' : 'NO';
        }
    
        private function getFrozenAttribute()
        {
            return $this->getSerializedAttribute('frozen');
        }
    
        protected function getSerializedAttribute($localName)
        {
            $namespaceURI = FreezableDOMDocument::NS_URI;
            $prefix = FreezableDOMDocument::NS_PREFIX;
    
            if ($this->hasAttributeNS($namespaceURI, $localName)) {
                $attrib = $this->getAttributeNodeNS($namespaceURI, $localName);
            } else {
                $this->ownerDocument->documentElement->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $prefix, $namespaceURI);
                $attrib = $this->ownerDocument->createAttributeNS($namespaceURI, $prefix . ':' . $localName);
                $attrib = $this->appendChild($attrib);
            }
            return $attrib;
        }
    }
    
    class FreezableDOMDocument extends DOMDocument implements Serializable
    {
        const NS_URI = '/frozen.org/freeze/2';
        const NS_PREFIX = 'freeze';
    
        public function __construct()
        {
            parent::__construct();
            $this->registerNodeClasses();
        }
    
        private function registerNodeClasses()
        {
            $this->registerNodeClass('DOMElement', 'FreezableDOMElement');
        }
    
        /**
         * @return DOMNodeList
         */
        private function getNodes()
        {
            $xp = new DOMXPath($this);
            return $xp->query('//*');
        }
    
        public function serialize()
        {
            return parent::saveXML();
        }
    
        public function unserialize($serialized)
        {
            parent::__construct();
            $this->registerNodeClasses();
            $this->loadXML($serialized);
        }
    
        public function saveBareXML()
        {
            $doc = new DOMDocument();
            $doc->loadXML(parent::saveXML());
            $xp = new DOMXPath($doc);
            foreach ($xp->query('//@*[namespace-uri()=\'' . self::NS_URI . '\']') as $attr) {
                /* @var $attr DOMAttr */
                $attr->parentNode->removeAttributeNode($attr);
            }
            $doc->documentElement->removeAttributeNS(self::NS_URI, self::NS_PREFIX);
            return $doc->saveXML();
        }
    
        public function saveXMLDirect()
        {
            return parent::saveXML();
        }
    }
    
    $doc = new FreezableDOMDocument();
    $doc->loadXML('<root><child></child></root>');
    $doc->documentElement->setFrozen(TRUE);
    $child = $doc->getElementsByTagName('child')->item(0);
    $child->setFrozen(TRUE);
    
    echo "Plain XML:\n", $doc->saveXML(), "\n";
    echo "Bare XML:\n", $doc->saveBareXML(), "\n";
    
    $serialized = serialize($doc);
    
    echo "Serialized:\n", $serialized, "\n";
    
    $newDoc = unserialize($serialized);
    
    printf("Document Element is frozen (should be): %s\n", $newDoc->documentElement->getFrozen() ? 'YES' : 'NO');
    printf("Child Element is frozen (should be): %s\n", $newDoc->getElementsByTagName('child')->item(0)->getFrozen() ? 'YES' : 'NO');
    

    It’s not really feature complete but a working demo. It’s possible to obtain the full XML without the additional “freeze” data.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I'm trying to create an if statement in PHP that prevents a single post
That's pretty much it. I'm using Nokogiri to scrape a web page what has
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but
I would like to count the length of a string with PHP. The string
I am trying to understand how to use SyndicationItem to display feed which is
I have a jquery bug and I've been looking for hours now, I can't
Basically, what I'm trying to create is a page of div tags, each has

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.