[ Index ]
 

Code source de phpMyVisites 2.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/libs/Xml/ -> Unserializer.php (source)

   1  <?PHP
   2  /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

   3  
   4  /**

   5   * XML_Unserializer

   6   *

   7   * Parses any XML document into PHP data structures.

   8   *

   9   * PHP versions 4 and 5

  10   *

  11   * LICENSE: This source file is subject to version 3.0 of the PHP license

  12   * that is available through the world-wide-web at the following URI:

  13   * http://www.php.net/license/3_0.txt.  If you did not receive a copy of

  14   * the PHP License and are unable to obtain it through the web, please

  15   * send a note to license@php.net so we can mail you a copy immediately.

  16   *

  17   * @category   XML

  18   * @package    XML_Serializer

  19   * @author     Stephan Schmidt <schst@php.net>

  20   * @copyright  1997-2005 The PHP Group

  21   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0

  22   * @version    CVS: $Id: Unserializer.php,v 1.1 2005/12/06 01:50:39 matthieu_ Exp $

  23   * @link       http://pear.php.net/package/XML_Serializer

  24   * @see        XML_Unserializer

  25   */
  26  
  27  /**

  28   * uses PEAR error managemt

  29   */
  30  require_once 'PEAR.php';
  31  
  32  /**

  33   * uses XML_Parser to unserialize document

  34   */
  35  require_once 'Xml/Parser.php';
  36  
  37  /**

  38   * error code for no serialization done

  39   */
  40  define('XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION', 151);
  41  
  42  /**

  43   * XML_Unserializer

  44   *

  45   * class to unserialize XML documents that have been created with

  46   * XML_Serializer. To unserialize an XML document you have to add

  47   * type hints to the XML_Serializer options.

  48   *

  49   * If no type hints are available, XML_Unserializer will guess how

  50   * the tags should be treated, that means complex structures will be

  51   * arrays and tags with only CData in them will be strings.

  52   *

  53   * <code>

  54   * require_once 'XML/Unserializer.php';

  55   *

  56   * //  be careful to always use the ampersand in front of the new operator

  57   * $unserializer = &new XML_Unserializer();

  58   *

  59   * $unserializer->unserialize($xml);

  60   *

  61   * $data = $unserializer->getUnserializedData();

  62   * <code>

  63   *

  64   * Possible options for the Unserializer are:

  65   *

  66   * 1. complexTypes => array|object

  67   * This is needed, when unserializing XML files w/o type hints. If set to

  68   * 'array' (default), all nested tags will be arrays, if set to 'object'

  69   * all nested tags will be objects, that means you have read access like:

  70   *

  71   * <code>

  72   * require_once 'XML/Unserializer.php';

  73   * $options = array('complexType' => 'object');

  74   * $unserializer = &new XML_Unserializer($options);

  75   *

  76   * $unserializer->unserialize('http://pear.php.net/rss.php');

  77   *

  78   * $rss = $unserializer->getUnserializedData();

  79   * echo $rss->channel->item[3]->title;

  80   * </code>

  81   *

  82   * 2. keyAttribute

  83   * This lets you specify an attribute inside your tags, that are used as key

  84   * for associative arrays or object properties.

  85   * You will need this if you have XML that looks like this:

  86   *

  87   * <users>

  88   *   <user handle="schst">Stephan Schmidt</user>

  89   *   <user handle="ssb">Stig S. Bakken</user>

  90   * </users>

  91   *

  92   * Then you can use:

  93   * <code>

  94   * require_once 'XML/Unserializer.php';

  95   * $options = array('keyAttribute' => 'handle');

  96   * $unserializer = &new XML_Unserializer($options);

  97   *

  98   * $unserializer->unserialize($xml, false);

  99   *

 100   * $users = $unserializer->getUnserializedData();

 101   * </code>

 102   *

 103   * @category   XML

 104   * @package    XML_Serializer

 105   * @author     Stephan Schmidt <schst@php.net>

 106   * @copyright  1997-2005 The PHP Group

 107   * @license    http://www.php.net/license/3_0.txt  PHP License 3.0

 108   * @version    Release: 0.16.0

 109   * @link       http://pear.php.net/package/XML_Serializer

 110   * @see        XML_Serializer

 111   */
 112  class XML_Unserializer extends PEAR
 113  {
 114  
 115     /**

 116      * default options for the serialization

 117      *

 118      * @access private

 119      * @var    array

 120      */
 121      var $_defaultOptions = array(
 122                           'complexType'       => 'array',                // complex types will be converted to arrays, if no type hint is given
 123                           'keyAttribute'      => '_originalKey',         // get array key/property name from this attribute
 124                           'typeAttribute'     => '_type',                // get type from this attribute
 125                           'classAttribute'    => '_class',               // get class from this attribute (if not given, use tag name)
 126                           'tagAsClass'        => true,                   // use the tagname as the classname
 127                           'defaultClass'      => 'stdClass',             // name of the class that is used to create objects
 128                           'parseAttributes'   => false,                  // parse the attributes of the tag into an array
 129                           'attributesArray'   => false,                  // parse them into sperate array (specify name of array here)
 130                           'prependAttributes' => '',                     // prepend attribute names with this string
 131                           'contentName'       => '_content',             // put cdata found in a tag that has been converted to a complex type in this key
 132                           'tagMap'            => array(),                // use this to map tagnames
 133                           'forceEnum'         => array(),                // these tags will always be an indexed array
 134                           'encoding'          => null,                   // specify the encoding character of the document to parse
 135                           'targetEncoding'    => null,                   // specify the target encoding
 136                           'decodeFunction'    => null,                   // function used to decode data
 137                           'returnResult'      => false                   // unserialize() returns the result of the unserialization instead of true
 138                          );
 139  
 140     /**

 141      * actual options for the serialization

 142      *

 143      * @access public

 144      * @var    array

 145      */
 146      var $options = array();
 147  
 148     /**

 149      * unserialized data

 150      *

 151      * @access private

 152      * @var    string

 153      */
 154      var $_unserializedData = null;
 155  
 156     /**

 157      * name of the root tag

 158      *

 159      * @access private

 160      * @var    string

 161      */
 162      var $_root = null;
 163  
 164     /**

 165      * stack for all data that is found

 166      *

 167      * @access private

 168      * @var    array

 169      */
 170      var $_dataStack  =   array();
 171  
 172     /**

 173      * stack for all values that are generated

 174      *

 175      * @access private

 176      * @var    array

 177      */
 178      var $_valStack  =   array();
 179  
 180     /**

 181      * current tag depth

 182      *

 183      * @access private

 184      * @var    int

 185      */
 186      var $_depth = 0;
 187  
 188     /**

 189      * XML_Parser instance

 190      *

 191      * @access   private

 192      * @var      object XML_Parser

 193      */
 194      var $_parser = null;
 195      
 196     /**

 197      * constructor

 198      *

 199      * @access   public

 200      * @param    mixed   $options    array containing options for the unserialization

 201      */
 202      function XML_Unserializer($options = null)
 203      {
 204          if (is_array($options)) {
 205              $this->options = array_merge($this->_defaultOptions, $options);
 206          } else {
 207              $this->options = $this->_defaultOptions;
 208          }
 209      }
 210  
 211     /**

 212      * return API version

 213      *

 214      * @access   public

 215      * @static

 216      * @return   string  $version API version

 217      */
 218      function apiVersion()
 219      {
 220          return '0.16.0';
 221      }
 222  
 223     /**

 224      * reset all options to default options

 225      *

 226      * @access   public

 227      * @see      setOption(), XML_Unserializer(), setOptions()

 228      */
 229      function resetOptions()
 230      {
 231          $this->options = $this->_defaultOptions;
 232      }
 233  
 234     /**

 235      * set an option

 236      *

 237      * You can use this method if you do not want to set all options in the constructor

 238      *

 239      * @access   public

 240      * @see      resetOption(), XML_Unserializer(), setOptions()

 241      */
 242      function setOption($name, $value)
 243      {
 244          $this->options[$name] = $value;
 245      }
 246  
 247     /**

 248      * sets several options at once

 249      *

 250      * You can use this method if you do not want to set all options in the constructor

 251      *

 252      * @access   public

 253      * @see      resetOption(), XML_Unserializer(), setOption()

 254      */
 255      function setOptions($options)
 256      {
 257          $this->options = array_merge($this->options, $options);
 258      }
 259  
 260     /**

 261      * unserialize data

 262      *

 263      * @access   public

 264      * @param    mixed    $data     data to unserialize (string, filename or resource)

 265      * @param    boolean  $isFile   data should be treated as a file

 266      * @param    array    $options  options that will override the global options for this call

 267      * @return   boolean  $success

 268      */
 269      function unserialize($data, $isFile = false, $options = null)
 270      {
 271          $this->_unserializedData = null;
 272          $this->_root = null;
 273  
 274          // if options have been specified, use them instead

 275          // of the previously defined ones

 276          if (is_array($options)) {
 277              $optionsBak = $this->options;
 278              if (isset($options['overrideOptions']) && $options['overrideOptions'] == true) {
 279                  $this->options = array_merge($this->_defaultOptions, $options);
 280              } else {
 281                  $this->options = array_merge($this->options, $options);
 282              }
 283          } else {
 284              $optionsBak = null;
 285          }
 286  
 287          $this->_valStack = array();
 288          $this->_dataStack = array();
 289          $this->_depth = 0;
 290  
 291          $this->_createParser();
 292          
 293          if (is_string($data)) {
 294              if ($isFile) {
 295                  $result = $this->_parser->setInputFile($data);
 296                  if (PEAR::isError($result)) {
 297                      return $result;
 298                  }
 299                  $result = $this->_parser->parse();
 300              } else {
 301                  $result = $this->_parser->parseString($data,true);
 302              }
 303          } else {
 304             $this->_parser->setInput($data);
 305             $result = $this->_parser->parse();
 306          }
 307  
 308          if ($this->options['returnResult'] === true) {
 309              $return = $this->_unserializedData;
 310          } else {
 311              $return = true;
 312          }
 313  
 314          if ($optionsBak !== null) {
 315              $this->options = $optionsBak;
 316          }
 317  
 318          if (PEAR::isError($result)) {
 319              return $result;
 320          }
 321  
 322          return $return;
 323      }
 324  
 325     /**

 326      * get the result of the serialization

 327      *

 328      * @access public

 329      * @return string  $serializedData

 330      */
 331      function getUnserializedData()
 332      {
 333          if ($this->_root === null) {
 334              return $this->raiseError('No unserialized data available. Use XML_Unserializer::unserialize() first.', XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION);
 335          }
 336          return $this->_unserializedData;
 337      }
 338  
 339     /**

 340      * get the name of the root tag

 341      *

 342      * @access public

 343      * @return string  $rootName

 344      */
 345      function getRootName()
 346      {
 347          if ($this->_root === null) {
 348              return $this->raiseError('No unserialized data available. Use XML_Unserializer::unserialize() first.', XML_UNSERIALIZER_ERROR_NO_UNSERIALIZATION);
 349          }
 350          return $this->_root;
 351      }
 352  
 353     /**

 354      * Start element handler for XML parser

 355      *

 356      * @access private

 357      * @param  object $parser  XML parser object

 358      * @param  string $element XML element

 359      * @param  array  $attribs attributes of XML tag

 360      * @return void

 361      */
 362      function startHandler($parser, $element, $attribs)
 363      {
 364          if (isset($attribs[$this->options['typeAttribute']])) {
 365              $type = $attribs[$this->options['typeAttribute']];
 366          } else {
 367              $type = 'string';
 368          }
 369  
 370          if ($this->options['decodeFunction'] !== null) {
 371              $element = call_user_func($this->options['decodeFunction'], $element);
 372              $attribs = array_map($this->options['decodeFunction'], $attribs);
 373          }
 374          
 375          $this->_depth++;
 376          $this->_dataStack[$this->_depth] = null;
 377  
 378          if (is_array($this->options['tagMap']) && isset($this->options['tagMap'][$element])) {
 379              $element = $this->options['tagMap'][$element];
 380          }
 381  
 382          $val = array(
 383                       'name'         => $element,
 384                       'value'        => null,
 385                       'type'         => $type,
 386                       'childrenKeys' => array(),
 387                       'aggregKeys'   => array()
 388                      );
 389  
 390          if ($this->options['parseAttributes'] == true && (count($attribs) > 0)) {
 391              $val['children'] = array();
 392              $val['type']  = $this->options['complexType'];
 393              $val['class'] = $element;
 394  
 395              if ($this->options['attributesArray'] != false) {
 396                  $val['children'][$this->options['attributesArray']] = $attribs;
 397              } else {
 398                  foreach ($attribs as $attrib => $value) {
 399                      $val['children'][$this->options['prependAttributes'].$attrib] = $value;
 400                  }
 401              }
 402          }
 403  
 404          $keyAttr = false;
 405          
 406          if (is_string($this->options['keyAttribute'])) {
 407              $keyAttr = $this->options['keyAttribute'];
 408          } elseif (is_array($this->options['keyAttribute'])) {
 409              if (isset($this->options['keyAttribute'][$element])) {
 410                  $keyAttr = $this->options['keyAttribute'][$element];
 411              } elseif (isset($this->options['keyAttribute']['__default'])) {
 412                  $keyAttr = $this->options['keyAttribute']['__default'];
 413              }
 414          }
 415          
 416          if ($keyAttr !== false && isset($attribs[$keyAttr])) {
 417              $val['name'] = $attribs[$keyAttr];
 418          }
 419  
 420          if (isset($attribs[$this->options['classAttribute']])) {
 421              $val['class'] = $attribs[$this->options['classAttribute']];
 422          }
 423  
 424          array_push($this->_valStack, $val);
 425      }
 426  
 427     /**

 428      * End element handler for XML parser

 429      *

 430      * @access private

 431      * @param  object XML parser object

 432      * @param  string

 433      * @return void

 434      */
 435      function endHandler($parser, $element)
 436      {
 437          $value = array_pop($this->_valStack);
 438          $data  = trim($this->_dataStack[$this->_depth]);
 439  
 440          // adjust type of the value

 441          switch(strtolower($value['type'])) {
 442  
 443              // unserialize an object

 444              case 'object':
 445                  if (isset($value['class'])) {
 446                      $classname  = $value['class'];
 447                  } else {
 448                      $classname = '';
 449                  }
 450                  // instantiate the class

 451                  if ($this->options['tagAsClass'] === true && class_exists($classname)) {
 452                      $value['value'] = &new $classname;
 453                  } else {
 454                      $value['value'] = &new $this->options['defaultClass'];
 455                  }
 456                  if ($data !== '') {
 457                      $value['children'][$this->options['contentName']] = $data;
 458                  }
 459  
 460                  // set properties

 461                  foreach ($value['children'] as $prop => $propVal) {
 462                      // check whether there is a special method to set this property

 463                      $setMethod = 'set'.$prop;
 464                      if (method_exists($value['value'], $setMethod)) {
 465                          call_user_func(array(&$value['value'], $setMethod), $propVal);
 466                      } else {
 467                          $value['value']->$prop = $propVal;
 468                      }
 469                  }
 470                  //  check for magic function

 471                  if (method_exists($value['value'], '__wakeup')) {
 472                      $value['value']->__wakeup();
 473                  }
 474                  break;
 475  
 476              // unserialize an array

 477              case 'array':
 478                  if ($data !== '') {
 479                      $value['children'][$this->options['contentName']] = $data;
 480                  }
 481                  if (isset($value['children'])) {
 482                      $value['value'] = $value['children'];
 483                  } else {
 484                      $value['value'] = array();
 485                  }
 486                  break;
 487  
 488              // unserialize a null value

 489              case 'null':
 490                  $data = null;
 491                  break;
 492  
 493              // unserialize a resource => this is not possible :-(

 494              case 'resource':
 495                  $value['value'] = $data;
 496                  break;
 497  
 498              // unserialize any scalar value

 499              default:
 500                  settype($data, $value['type']);
 501                  $value['value'] = $data;
 502                  break;
 503          }
 504          $parent = array_pop($this->_valStack);
 505          if ($parent === null) {
 506              $this->_unserializedData = &$value['value'];
 507              $this->_root = &$value['name'];
 508              return true;
 509          } else {
 510              // parent has to be an array

 511              if (!isset($parent['children']) || !is_array($parent['children'])) {
 512                  $parent['children'] = array();
 513                  if (!in_array($parent['type'], array('array', 'object'))) {
 514                      $parent['type'] = $this->options['complexType'];
 515                      if ($this->options['complexType'] == 'object') {
 516                          $parent['class'] = $parent['name'];
 517                      }
 518                  }
 519              }
 520  
 521              if (!empty($value['name'])) {
 522                  // there already has been a tag with this name

 523                  if (in_array($value['name'], $parent['childrenKeys']) || in_array($value['name'], $this->options['forceEnum'])) {
 524                      // no aggregate has been created for this tag

 525                      if (!in_array($value['name'], $parent['aggregKeys'])) {
 526                          if (isset($parent['children'][$value['name']])) {
 527                              $parent['children'][$value['name']] = array($parent['children'][$value['name']]);
 528                          } else {
 529                              $parent['children'][$value['name']] = array();
 530                          }
 531                          array_push($parent['aggregKeys'], $value['name']);
 532                      }
 533                      array_push($parent['children'][$value['name']], $value['value']);
 534                  } else {
 535                      $parent['children'][$value['name']] = &$value['value'];
 536                      array_push($parent['childrenKeys'], $value['name']);
 537                  }
 538              } else {
 539                  array_push($parent['children'],$value['value']);
 540              }
 541              array_push($this->_valStack, $parent);
 542          }
 543  
 544          $this->_depth--;
 545      }
 546  
 547     /**

 548      * Handler for character data

 549      *

 550      * @access private

 551      * @param  object XML parser object

 552      * @param  string CDATA

 553      * @return void

 554      */
 555      function cdataHandler($parser, $cdata)
 556      {
 557          $this->_dataStack[$this->_depth] .= $cdata;
 558      }
 559  
 560     /**

 561      * create the XML_Parser instance

 562      *

 563      * @access    private

 564      * @return    boolean

 565      */
 566      function _createParser()
 567      {
 568          if (is_object($this->_parser)) {
 569              $this->_parser->free();
 570              unset($this->_parser);
 571          }
 572          $this->_parser = &new XML_Parser($this->options['encoding'], 'event', $this->options['targetEncoding']);
 573          $this->_parser->folding = false;
 574          $this->_parser->setHandlerObj($this);
 575          return true;
 576      }
 577  }
 578  ?>


Généré le : Mon Nov 26 14:10:01 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics