As of version 5.2.5, this is wrong:
> Note: If you want to serialize non-ASCII characters you
> have to convert your data to UTF-8 first (see utf8_encode()
> and iconv()).
Serializing a string with WDDX will always convert it from ISO-8859-1 to UTF-8, no matter what the original encoding is. So if your data already are UTF-8, you get just gibberish.
You can restore the original encoding by using utf8_decode on the serialized wddx data, even though your original data may use chars not included in ISO-8859-1:
<?php
header("Content-Type: text/xml;encoding=utf-8");
echo utf8_decode(wddx_serialize_value("안녕 하세요"));
?>
(This is why I dislike PHP, sorry)
WDDX Functions
소개
These functions are intended for work with » WDDX.
요구 조건
In order to use WDDX, you will need to install the expat library (which comes with Apache 1.3.7 or higher).
설치
After installing expat compile PHP with --enable-wddx.
PHP 윈도우 버전에서는 이 확장에 대한 지원이 포함되어 있습니다. 이 함수들을 이용하기 위해서 추가로 확장을 읽어들일 필요가 없습니다.
실행시 설정
이 확장은 php.ini 설정이 존재하지 않습니다.
자원형
This extension defines a WDDX packet identifier returned by wddx_packet_start().
예약 상수
이 확장은 상수를 정의하지 않습니다.
예제
All the functions that serialize variables use the first element of an array to determine whether the array is to be serialized into an array or structure. If the first element has string key, then it is serialized into a structure, otherwise, into an array.
Example#1 Serializing a single value with WDDX
<?php
echo wddx_serialize_value("PHP to WDDX packet example", "PHP packet");
?>
This example will produce:
<wddxPacket version='1.0'><header comment='PHP packet'/><data> <string>PHP to WDDX packet example</string></data></wddxPacket>
Example#2 Using incremental packets with WDDX
<?php
$pi = 3.1415926;
$packet_id = wddx_packet_start("PHP");
wddx_add_vars($packet_id, "pi");
/* Suppose $cities came from database */
$cities = array("Austin", "Novato", "Seattle");
wddx_add_vars($packet_id, "cities");
$packet = wddx_packet_end($packet_id);
echo $packet;
?>
This example will produce:
<wddxPacket version='1.0'><header comment='PHP'/><data><struct> <var name='pi'><number>3.1415926</number></var><var name='cities'> <array length='3'><string>Austin</string><string>Novato</string> <string>Seattle</string></array></var></struct></data></wddxPacket>
Note: If you want to serialize non-ASCII characters you have to convert your data to UTF-8 first (see utf8_encode() and iconv()).
Table of Contents
- wddx_add_vars — Add variables to a WDDX packet with the specified ID
- wddx_deserialize — Alias of wddx_unserialize
- wddx_packet_end — Ends a WDDX packet with the specified ID
- wddx_packet_start — Starts a new WDDX packet with structure inside it
- wddx_serialize_value — Serialize a single value into a WDDX packet
- wddx_serialize_vars — Serialize variables into a WDDX packet
- wddx_unserialize — Unserializes a WDDX packet
WDDX
14-Mar-2008 03:03
23-Feb-2008 10:50
I'm horrible, forgot to include a helper function:
function getchild($node)
{
if(count($node) > 1) echo "warning: node $node has more than 1 child";
foreach($node->children() as $name => $subnode) {}
return array($subnode, $name);
}
23-Feb-2008 10:49
If your PHP doesn't have wddx support installed, and you need it, and you don't want to install PEAR just for wddx, try this short piece of code, based on SimpleXML:
//can read any wddx file generated from php arrays. assumes var elements are only inside struct elements and that only one packet exists.
function wddx_read_node($node, $type)
{
switch($type)
{
case "boolean":
return (string)$node;
case "number":
case "binary":
case "string":
return (string)$node;
case "null":
return null;
case "array":
$a = array();
foreach($node as $subtype => $subnode)
{
$a[] = wddx_read_node($subnode, $subtype);
}
return $a;
case "struct":
$a = array();
foreach($node as $subtype => $subnode)
{
list($key, $value) = wddx_read_node($subnode, $subtype); //must be a var element
$a[$key] = $value;
}
return $a;
case "var":
list($subnode, $subtype) = getchild($node);
return array((string)$node["name"], wddx_read_node($subnode, $subtype));
case "data":
list($subnode, $subtype) = getchild($node);
return wddx_read_node($subnode, $subtype);
}
}
function wddx_read($string)
{
$xml = simplexml_load_string($string);
$d = wddx_read_node($xml->data, "data");
return $d;
}
important notice: this one may not work with all wddx input. multiple packets or variables outside a "struct" are not supported. basically, you always get a PHP (associative) array, never something else. feel free to make additions.
12-Aug-2007 02:09
To bradburn at kiwi dot de:
PHP is only capable of serializing properly variables which match one of its native (scalar) types (See http://php.net/types). Which means that only variables of type booleans, integers, floating point numbers, string and NULL will be serialized properly.
I think there are two exceptions though:
- arrays are serialized by processing them recursively, so if its only composed of the above mentioned types, you should be fine.
- floating point numbers and integers may use the same representation while serialized in WDDX (I don't know much about WDDX, so I'm not 100% sure about this statement).
An interesting case would be whether objects can be serialized or not...
15-Jul-2004 05:53
PHP's WDDX is useful only for exchanging data between PHP applications, but definetly not for exchanging data between different languages (which actually defeats the purpose of WDDX).
For example:
$hash1 = array ("2" => "Two", "4" => "Four", "5" => "Five");
$hash2 = array ("0" => "Zero", "1" => "One", "2" => "Two");
$hash1 will be serialized as hash, but
$hash2 will be serialized as array/list, because the key happen to be a sequence starting from 0.
Unless the library provide a way for users to specify the type, it can never be used for cross-platform data exchange.
21-Nov-2003 05:08
To insert arrays into a wddx variable here is a fine way to do it:
<?php
$sql = 'SELECT * FROM example';
$query = mysql_query($sql, $db) or die(mysql_error());
while($result = mysql_fetch_array($query)) {
$id[] = $result[ 'id'];
$name[] = $result['name'];
$description[] = $result[$prefix . 'description'];
}
mysql_free_result($query);
wddx_add_vars($packet_id, "id");
wddx_add_vars($packet_id, "name");
wddx_add_vars($packet_id, "description");
$wddxSerializeValue = wddx_packet_end($packet_id);
?>
wddx isn't 100% perl compatible .. I have an wddx file infront of me and it only works with php so better don't use it
30-Jul-2002 07:02
With ref to the above comment about typing, I have found that -- oddly enough -- PHP's WDDX supports the following WDDX types: null, boolean (true/false), number and string, *but* not date-time.
as an example, use the following values in an array that you then serialize:
$number = 5,
$null = NULL,
$bool = true,
$string = 'this is a string'.
they will all serialize correctly, e.g. the third entry comes out as:
<var name='bool'><boolean value='true'/></var>
i have tried with the 'official' format for WDDX 'datetime', e.g. '1998-9-15T09:05:32+4:0' (from the DTD @ http://www.openwddx.org/downloads/dtd/wddx_dtd_10.txt) but have only succeeded in getting this encoded as a 'string' type.
if anyone else has any more information on this, it would be welcome. i would like to store the variables in 'appropriate' fields in a database, and the fact that only datetime is not supported is slightly irritating -- otherwise it would be a very useful function.
17-Nov-2000 01:32
Tutorial here :
XML and PHP. Part 1: Using the WDDX functions
http://www.phpbuilder.net/columns/jesus20000402.php3
18-Oct-1999 08:45
Since there aren't any examples of reversing the process, here's one. If you had the packet produced by the above example (without the htmlentities() call), you could retrieve the values like this:
<?php
$value = wddx_deserialize($packet);
print "pi is:<br>" . $value["pi"] . "<p>\n";
print "cities is:<br>\n";
while (list($key, $val) = each($value["cities"])) {
print "$key => $val<br>\n";
}
?>
which outputs:
<pre>
pi is:
3.1415926
cities is:
0 => Austin
1 => Novato
2 => Seattle
</pre>
