Source for file Unserializer.php
Documentation is available at Unserializer.php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2002 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.0 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Stephan Schmidt <schst@php-tools.net> |
// +----------------------------------------------------------------------+
// $Id: Unserializer.php,v 1.23 2004/11/06 15:49:52 schst Exp $
* uses PEAR error managemt
* uses XML_Parser to unserialize document
require_once 'XML/Parser.php';
* error code for no serialization done
define('XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION', 151 );
* class to unserialize XML documents that have been created with
* XML_Serializer. To unserialize an XML document you have to add
* type hints to the XML_Serializer options.
* If no type hints are available, XML_Unserializer will guess how
* the tags should be treated, that means complex structures will be
* arrays and tags with only CData in them will be strings.
* require_once 'XML/Unserializer.php';
* // be careful to always use the ampersand in front of the new operator
* $unserializer = &new XML_Unserializer();
* $unserializer->unserialize($xml);
* $data = $unserializer->getUnserializedData();
* Possible options for the Unserializer are:
* 1. complexTypes => array|object
* This is needed, when unserializing XML files w/o type hints. If set to
* 'array' (default), all nested tags will be arrays, if set to 'object'
* all nested tags will be objects, that means you have read access like:
* require_once 'XML/Unserializer.php';
* $options = array('complexType' => 'object');
* $unserializer = &new XML_Unserializer($options);
* $unserializer->unserialize('http://pear.php.net/rss.php');
* $rss = $unserializer->getUnserializedData();
* echo $rss->channel->item[3]->title;
* This lets you specify an attribute inside your tags, that are used as key
* for associative arrays or object properties.
* You will need this if you have XML that looks like this:
* <user handle="schst">Stephan Schmidt</user>
* <user handle="ssb">Stig S. Bakken</user>
* require_once 'XML/Unserializer.php';
* $options = array('keyAttribute' => 'handle');
* $unserializer = &new XML_Unserializer($options);
* $unserializer->unserialize($xml, false);
* $users = $unserializer->getUnserializedData();
* @package XML_Serializer
* @author Stephan Schmidt <schst@php-tools.net>
* default options for the serialization
* @var array $_defaultOptions
var $_defaultOptions = array (
'complexType' => 'array', // complex types will be converted to arrays, if no type hint is given
'keyAttribute' => '_originalKey', // get array key/property name from this attribute
'typeAttribute' => '_type', // get type from this attribute
'classAttribute' => '_class', // get class from this attribute (if not given, use tag name)
'parseAttributes' => false , // parse the attributes of the tag into an array
'attributesArray' => false , // parse them into sperate array (specify name of array here)
'prependAttributes' => '', // prepend attribute names with this string
'contentName' => '_content', // put cdata found in a tag that has been converted to a complex type in this key
'tagMap' => array (), // use this to map tagnames
'forceEnum' => array (), // these tags will always be an indexed array
'encoding' => null // specify the encoding character of the document to parse
* actual options for the serialization
* do not use case folding
* @var string $_serializedData
var $_unserializedData = null;
* stack for all data that is found
var $_dataStack = array ();
* stack for all values that are generated
var $_valStack = array ();
* @param mixed $options array containing options for the serialization
$this->options = array_merge($this->_defaultOptions, $options);
$this->options = $this->_defaultOptions;
// reset parser and properties
$this->XML_Parser ($this->options['encoding'],'event');
* @return string $version API version
* reset all options to default options
* @see setOption(), XML_Unserializer(), setOptions()
$this->options = $this->_defaultOptions;
* You can use this method if you do not want to set all options in the constructor
* @see resetOption(), XML_Unserializer(), setOptions()
$this->options[$name] = $value;
* sets several options at once
* You can use this method if you do not want to set all options in the constructor
* @see resetOption(), XML_Unserializer(), setOption()
$this->options = array_merge($this->options, $options);
* @param mixed $data data to unserialize (string, filename or resource)
* @param boolean $isFile string should be treated as a file
* @return boolean $success
function unserialize($data, $isFile = false , $options = null )
$this->_unserializedData = null;
// if options have been specified, use them instead
// of the previously defined ones
$optionsBak = $this->options;
if (isset ($options['overrideOptions']) && $options['overrideOptions'] == true ) {
$this->options = array_merge($this->_defaultOptions, $options);
$this->options = array_merge($this->options, $options);
$this->_valStack = array ();
$this->_dataStack = array ();
$result = $this->setInputFile ($data);
if (PEAR ::isError ($result)) {
$result = $this->parse ();
$result = $this->parseString ($data,true );
$result = $this->parse ();
if ($optionsBak !== null ) {
$this->options = $optionsBak;
if (PEAR ::isError ($result)) {
* get the result of the serialization
* @return string $serializedData
if ($this->_root === null ) {
return $this->_unserializedData;
* get the name of the root tag
* @return string $rootName
if ($this->_root === null ) {
* Start element handler for XML parser
* @param object $parser XML parser object
* @param string $element XML element
* @param array $attribs attributes of XML tag
function startHandler ($parser, $element, $attribs)
if (isset ($attribs[$this->options['typeAttribute']])) {
$type = $attribs[$this->options['typeAttribute']];
$this->_dataStack[$this->_depth] = null;
'childrenKeys' => array (),
if ($this->options['parseAttributes'] == true && (count($attribs) > 0 )) {
$val['children'] = array ();
$val['type'] = $this->options['complexType'];
if ($this->options['attributesArray'] != false ) {
$val['children'][$this->options['attributesArray']] = $attribs;
foreach ($attribs as $attrib => $value) {
$val['children'][$this->options['prependAttributes']. $attrib] = $value;
if (is_string($this->options['keyAttribute'])) {
$keyAttr = $this->options['keyAttribute'];
} elseif (is_array($this->options['keyAttribute'])) {
if (isset ($this->options['keyAttribute'][$element])) {
$keyAttr = $this->options['keyAttribute'][$element];
} elseif (isset ($this->options['keyAttribute']['__default'])) {
$keyAttr = $this->options['keyAttribute']['__default'];
if ($keyAttr !== false && isset ($attribs[$keyAttr])) {
$val['name'] = $attribs[$keyAttr];
if (isset ($attribs[$this->options['classAttribute']])) {
$val['class'] = $attribs[$this->options['classAttribute']];
* End element handler for XML parser
* @param object XML parser object
function endHandler ($parser, $element)
$data = trim($this->_dataStack[$this->_depth]);
// adjust type of the value
if(isset ($value['class'])) {
$classname = $value['class'];
if (is_array($this->options['tagMap']) && isset ($this->options['tagMap'][$classname])) {
$classname = $this->options['tagMap'][$classname];
$value['value'] = &new $classname;
$value['value'] = &new stdClass;
$value['children'][$this->options['contentName']] = $data;
foreach($value['children'] as $prop => $propVal) {
// check whether there is a special method to set this property
$setMethod = 'set'. $prop;
$value['value']->$prop = $propVal;
// check for magic function
$value['value']->__wakeup ();
$value['children'][$this->options['contentName']] = $data;
if (isset ($value['children'])) {
$value['value'] = $value['children'];
$value['value'] = array ();
* unserialize a null value
* unserialize a resource => this is not possible :-(
* unserialize any scalar value
$this->_unserializedData = &$value['value'];
$this->_root = &$value['name'];
// parent has to be an array
if (!isset ($parent['children']) || !is_array($parent['children'])) {
$parent['children'] = array ();
if (!in_array($parent['type'], array ('array', 'object'))) {
$parent['type'] = $this->options['complexType'];
if ($this->options['complexType'] == 'object') {
$parent['class'] = $parent['name'];
if (!empty ($value['name'])) {
// there already has been a tag with this name
if (in_array($value['name'], $parent['childrenKeys']) || in_array($value['name'], $this->options['forceEnum'])) {
// no aggregate has been created for this tag
if (!in_array($value['name'], $parent['aggregKeys'])) {
if (isset ($parent['children'][$value['name']])) {
$parent['children'][$value['name']] = array ($parent['children'][$value['name']]);
$parent['children'][$value['name']] = array ();
array_push($parent['aggregKeys'], $value['name']);
array_push($parent['children'][$value['name']], $value['value']);
$parent['children'][$value['name']] = &$value['value'];
array_push($parent['childrenKeys'], $value['name']);
* Handler for character data
* @param object XML parser object
function cdataHandler ($parser, $cdata)
$this->_dataStack[$this->_depth] .= $cdata;
Documentation generated on Mon, 11 Mar 2019 13:58:25 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.
|