How to serialize / save DOMElement in $ _SESSION?

I am new to PHP, DOM and PHP DOM implementation. What I'm trying to do is save the root element DOMDocumentin a variable $_SESSIONso that I can access it and change it on subsequent page loads.

But I get an error in PHP when used $_SESSIONto save the state of DOMElement:

Warning: DOMNode :: appendChild () [domnode.appendchild]: Failed to get DOMElement

I read that the PHP DOMDocument object cannot be stored in the $_SESSIONoriginal. However, you can save it by preserving the serialization of the DOMDocument (for example, $_SESSION['dom'] = $dom->saveXML()).

I don't know if the same is true for storing a variable DOMElementin$_SESSIONbut this is what i tried. My reason for this is to use the extended DOMElement class with one additional property. I was hoping that by storing the root DOMElement in $ _SESSION, I could later retrieve the element and change this additional property and run a test, for example if (extraProperty === false) {do something; }. I also read that by storing a DOMDocument and then retrieving it, all elements are returned as objects from the native DOM classes. That is, even if I used the extended class to create the elements, the property that I later needed would not be available, because the link containing the link to the extended class object went out of scope - that’s why I'm trying this other thing. At first I tried to use an extended class (not included below), but got errors ...so I went back to using the DOMElement object to check if this problem is, but I still get the same errors. Here is 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;
?>

( , 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 . ?

+5
1

DOMElement $_SESSION. , , .

, DOMDocument, .

XML .

:

  • DOMDocument ( )
  • FreezableDOMElement ( )
  • FreezableDOMElement::$frozen .

, . , DOMDocument FreezableDOMElement . , , FALSE (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)

PHP setUserData (DOM Level 3), , , . , XML- (. Serializable). (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');

, . XML "".

+4

All Articles