Current File : //opt/RZphp73/includes/XML/Wddx.php |
<?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 304073 2010-10-05 10:08:43Z clockwerx $
* @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':
// see if the string is really a number (and not prefixed by 0 - eg oct.)
if ( is_numeric ($value)
&& (intval(0+$value) == $value)
&& (substr($value,0,1) != '0')) {
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);
*/