home *** CD-ROM | disk | FTP | other *** search
- <?php
- /**
- * XML_Wddx : WDDX serializer and deserializer (works with or without the wddx extension)
- *
- * PHP versions 4 and 5
- *
- * LICENSE: This source file is subject to version 3.0 of the PHP license
- * that is available through the world-wide-web at the following URI:
- * http://www.php.net/license/3_0.txt. If you did not receive a copy of
- * the PHP License and are unable to obtain it through the web, please
- * send a note to license@php.net so we can mail you a copy immediately.
- *
- * @category XML
- * @package XML_Wddx
- * @author Alan Knowles <alan@akbkhome.com>
- * @copyright 1997-2005 The PHP Group
- * @license http://www.php.net/license/3_0.txt PHP License 3.0
- * @version $Id: Wddx.php,v 1.8 2005/03/30 02:44:56 alan_k Exp $
- * @link http://pear.php.net/package/XML_Wddx
- *
- *
- * @abstract
- * serialization is done by $string = XML_Wddx::serialize($data);
- * deserialization is done by $data = XML_Wddx::deserialize($string);
- *
- */
-
- require_once 'XML/Parser.php';
-
- class XML_Wddx extends XML_Parser {
-
-
- /**
- *
- *
- * serialize a value
- * usage:
- * echo XML_Wddx::serialize($array);
- *
- * @param mixed value to serialize
- *
- *
- * @return string Serialize data.
- * @access public
- * @static
- */
-
-
- function serialize($value)
- {
- $x = new XML_Wddx;
- return "<wddxPacket version='1.0'><header/><data>\n".
- $x->indent(1) . trim($x->_serializeValue($value)) . "\n".
- $x->indent(-1) . "</data></wddxPacket>\n";
- }
-
- /**
- *
- *
- * de-serialize a value (uses wddx_deserialize if it is built in..)
- * usage:
- * echo XML_Wddx::deserialize($some_wddx_data);
- *
- * @param mixed value to serialize
- *
- *
- * @return mixed deserialized data..
- * @access public
- * @static
-
- */
-
- function deserialize($data)
- {
- if (function_exists('wddx_deserialize')) {
- return wddx_deserialize($data);
- }
- $t = &new XML_Wddx;
- $t->XML_Parser();
-
- $t->parseString($data);
- return $t->result['data'];
- }
-
-
- /**
- * The core method.. that serializes data.
- *
- * @param mixed value to serialize
- *
- * @return string serialized value.
- * @access private
- * @see see also methods.....
- */
-
-
- function _serializeValue($value)
- {
- switch (gettype($value)) {
- case 'string':
- if ( is_numeric ($value) && (intval(0+$value) == $value) ) {
- return "<number>$value</number>";
- }
- //$this->indent(1);
- return preg_match('/[^a-z0-9_ ]/i',$value) ?
- "\n".$this->indent(0).'<string><![CDATA['.$value."]]></string>\n" :
- "<string>$value</string>";
- //$this->indent(-1);
-
- case 'integer':
- case 'float':
- case 'double':
- return "<number>$value</number>";
-
- case 'boolean':
- return sprintf("<boolean value='%s'/>",$value ? 'true':'false');
-
- case 'object':
- // sleep - ignored ATM
- $ret = "\n".$this->indent()."<struct>\n".
- $this->indent(1)."<var name='php_class_name'><string>".get_class($value)."</string></var>\n";
-
- foreach(get_object_vars($value) as $k=>$v) {
- $ret .= $this->indent(0).sprintf("<var name='%s'>",$k);
- $this->indent(1);
- $ret .= $this->_serializeValue($v);
- $this->indent(-1);
- $ret .= ($ret{strlen($ret)-1} == "\n") ? $this->indent() : '';
- $ret .= "</var>\n";
- }
-
- $this->indent(-1);
- return $ret . $this->indent() . "</struct>\n";
-
- case 'array':
-
- $is_struct = (array_keys($value) !== range(0,sizeof($value)-1));
- $ret = "\n".$this->indent();
- $ret .= $is_struct ? "<struct>\n" : sprintf("<array length='%d'>",count($value)). "\n";
- $this->indent(1);
- foreach($value as $k=>$v) {
- $ret .= $this->indent(0);
- $ret .= $is_struct ? sprintf("<var name='%s'>",$k) : '';
- $this->indent(1);
- $ret .= $this->_serializeValue($v) ;
- $this->indent(-1);
- $ret .= ($ret{strlen($ret)-1} == "\n") ? $this->indent() : '';
- $ret .= $is_struct ? "</var>\n" : "\n";
- }
-
- $ret .= $this->indent(-1);
- $ret .= $is_struct ? '</struct>' : '</array>';
- return $ret . "\n";
- case 'resource': // BIG KLUDGE!!!!
- case 'NULL':
- return "<null/>";
-
- default:
- echo "not handled " . gettype($value);
- exit;
-
- }
-
- }
-
-
- /**
- * Current indent level.
- *
- * @var int level
- * @access private
- */
- var $_indent = 0;
-
-
-
- /**
- * get an indent string
- *
- * @param int change (indent increment or decrement)
- *
- * @return string spaces
- * @access private
- */
-
- function indent($add=0)
- {
- $this->_indent += $add;
- if ($add < 0) { // should not happen!!
- $add = 0;
- }
- return str_repeat(' ',$this->_indent);
- }
-
-
-
- /**
- * expat start handler.
- *
- * @return none
- * @access private
- * @see XML_Parser:startHandler
- */
- function startHandler($xp, $element, $attribs)
- {
- $ent = array('type'=>strtolower($element));
- // echo "S:";print_r(func_get_args());
-
- switch (strtolower($element)) {
- case 'wddxpacket':
- case 'header':
- break;
- case 'string':
- case 'binary':
- $ent['data'] = '';
- array_push($this->_stack,$ent);
- break;
-
- case 'number':
- $ent['data'] = 0;
- array_push($this->_stack,$ent);
- break;
- case 'boolean':
- $ent['data'] = false;
- array_push($this->_stack,$ent);
- break;
- case 'null':
- $ent['data'] = null;
- array_push($this->_stack,$ent);
- break;
-
-
- case 'char':
- if (isset($attribs['CODE'])) {
- $e = $this->_stackTop();
- $e['data'] .= chr(hexdec($attribs['CODE']));
- $this->_stackTop($e);
- }
- break;
-
- case 'struct':
- case 'array':
- $ent['data'] = array();
- array_push($this->_stack,$ent);
- break;
- case 'var':
- $ent['name'] = @$attribs['NAME'];
-
- array_push($this->_stack,$ent);
- break;
- case 'recordset':
- break; // not handled yet...
- }
-
- //echo "STACK:";print_r($this->stack);
- //echo "S:";print_r(func_get_args());
- }
- /**
- * expat end handler.
- *
- * @return none
- * @access private
- * @see XML_Parser:startHandler
- */
- function endHandler($xp, $element)
- {
- //echo "E:";print_r(func_get_args());
-
- if (!count($this->_stack)) {
- return;
- }
- $parent = null;
- switch (strtolower($element)) {
- case 'packet':
-
-
- case 'char':
- case 'recordset':
- return;
-
-
- case 'string':
- case 'binary':
- case 'number':
- case 'boolean':
- case 'null':
- case 'array':
- case 'struct':
- case 'var':
-
-
- $ent = array_pop($this->_stack);
- $parent = false;
- $parent = $this->_stackTop();
- if (!$parent) {
- $this->result = $ent;
- break;
- }
-
- // if this is a struct + php_class_name is set...
- if (($ent['type'] == 'struct') && isset($ent['data']['php_class_name'])) {
- $class = $ent['data']['php_class_name'];
- $obj = new $class;
- unset($ent['data']['php_class_name']);
- foreach($ent['data'] as $k=>$v) {
-
- $obj->$k = $v;
- }
- $ent['data'] = $obj;
- }
-
-
- // add ent to parent...
-
- if ($parent['type'] == 'var') {
- $parent['data'] = $ent['data'];
- break;
- }
-
- if ($ent['type'] == 'var') {
- if ($parent['type'] == 'struct') {
- if ($ent['name']) {
- $parent['data'][$ent['name']] = $ent['data'];
- } else {
- $parent['data'][] = $ent['data'];
- }
- break;
- }
- }
- if ($parent['type'] == 'array') {
- $parent['data'][] = $ent['data'];
- break;
- }
-
- $parent['data'] = $ent['data'];
-
-
- break;
-
- }
- // put it back ..
- $this->_stackTop($parent);
-
- // echo "STACK:";print_r($this->stack);
-
-
- //echo "E:";print_r(func_get_args());
- }
-
- /**
- * expat cdata handler.
- *
- * @return none
- * @access private
- * @see XML_Parser:cdataHandler
- */
- function cdataHandler($xp, $cdata)
- {
- //$ent = array('type'=>false);
- if (!count($this->_stack)) {
- return;
- }
-
- $ent = $this->_stackTop();
-
- //var_dump($ent);
- switch($ent['type']) {
- case 'string':
- case 'binary':
- $ent['data'] .= $cdata;
- break;
- case 'number':
- $ent['data'] = $cdata;
- break;
- case 'boolean':
- $ent['data'] = $cdata == 'true' ? true : false;
- break;
-
- case 'datetime': // not really handled...
- $ent['data'] = $cdata;
- break;
- default:
- return;
-
-
-
- }
- $this->_stackTop($ent);
- //echo "C:";print_r(func_get_args());
- //echo "STACK: "; print_r($this->stack);
- //echo "C:";print_r(func_get_args());
- }
- /**
- * expat default handler.
- *
- * @return none
- * @access private
- * @see XML_Parser::defaultHandler
- */
- function defaultHandler($xp, $cdata)
- {
- //echo "D:";print_r(func_get_args());
- }
- /**
- * Current indent level.
- *
- * @var array stack
- * @access private
- */
-
- var $_stack = array();
- /**
- * get/set top of stack values..
- *
- * @param array optional (array if it is to be changed..)
- * @return array|none (empty parameter = get)
- * @access private
- */
- function _stackTop($ent = null)
- {
-
- if ($ent != null) {
- $this->_stack[count($this->_stack)-1] = $ent;
- return;
- }
- if (count($this->_stack)) {
- return $this->_stack[count($this->_stack)-1];
-
- }
- return;
- }
-
-
-
-
- }
- /*
- // test...
- $o = new StdClass;
- $o->x = "vvvv";
- $ar = array(
- 'a' => 1,
- 'b' => "TESTING \n 123\n",
- 'c' => $o,
- 'd' => array('x','y','z')
- );
- print_r(XML_Wddx::serialize($ar));
-
- echo wddx_serialize_value($ar);
-
- */