Home » Web Services » SOAP » Bug #1404
xsd:dateTime members in complex types are serialized as xsd:string
Details
| Submitted | 2004-05-14 02:47 UTC |
|---|---|
| From | clawrence at optimiser dot com |
| Status | Open |
| Package | SOAP |
| PHP Version | 4.3.6 |
| OS | redhat 7.2 |
| Roadmaps | (Not assigned) |
Comments
[2004-05-14 02:47 UTC] clawrence at optimiser dot com
Description:
------------
DateTime members of complex types when used as output from a SOAP operation are mis-reported by PEAR::SOAP (0.8RC3 beta) as being string types (see echoDate2() for details).
The echoDate1() operation correctly reports the dateTime datatype primitive in it's response.
Reproduce code:
---------------
<?php
set_magic_quotes_runtime(0);
ini_set("magic_quotes_gpc", 0);
class SOAPDateWrap {
var $datefied;
function SOAPDateWrap ($datefied = NULL) {
$this->datefied = $datefied;
}
}
require_once 'SOAP/Value.php';
class SOAPEchoDateService {
var $__dispatch_map = array();
var $__typedef = array();
function SOAPEchoDateService() {
// Define the SOAPDateWrap Type
$this->__typedef['{http://www.optimiser.com/soap}SOAPDateWrap'] = array('datefied' => 'dateTime');
// Define the echoDate1 operation
$this->__dispatch_map['echoDate1'] = array('in' => array('inDate' => 'dateTime'), 'out' => array('outDate' => 'dateTime'));
// Define the echoDate2 operation
$this->__dispatch_map['echoDate2'] = array('in' => array('inDate' => 'dateTime'), 'out' => array('outDateWrap' => '{http://www.optimiser.com/soap}SOAPDateWrap'));
}
function __dispatch($methodname) {
if (isset($this->__dispatch_map[$methodname]))
return $this->__dispatch_map[$methodname];
return NULL;
}
function echoDate1($inDate) {
$outDate = $inDate;
return new SOAP_Value('outDate', 'dateTime', $outDate);
}
function echoDate2($inDate) {
$outDate = $inDate;
return new SOAP_Value('outDateWrap', '{http://www.optimiser.com/soap}SOAPDateWrap', new SOAPDateWrap($outDate));
}
}
require_once 'Log.php';
require_once 'SOAP/Server.php';
$log = &Log::singleton('file', '/tmp/echoDate.log', 'echoDate', array('mode' => 0666), LOG_INFO);
$server = new SOAP_Server;
$server->_auto_translation = true;
$soapclass = new SOAPEchoDateService();
$server->addObjectMap($soapclass,'urn:SOAPEchoDate');
if (isset($_SERVER['REQUEST_METHOD']) &&
$_SERVER['REQUEST_METHOD'] == 'POST') {
$log->log("[".getmypid()."] REQUEST: \n".$HTTP_RAW_POST_DATA);
ob_start();
$server->service($HTTP_RAW_POST_DATA);
$log->log("[".getmypid()."] RESPONSE: \n".ob_get_contents());
ob_end_flush();
} else {
require_once 'SOAP/Disco.php';
$disco = new SOAP_DISCO_Server($server,'SOAPEchoDate');
header("Content-type: text/xml");
if (isset($_SERVER['QUERY_STRING'])
&& strcasecmp($_SERVER['QUERY_STRING'], 'wsdl') == 0) {
echo $disco->getWSDL();
} else {
echo $disco->getDISCO();
}
exit;
}
?>
Expected result:
----------------
The datefied member of the SOAPDateWrap complex type returned from the echoDate2() operation should be of type xsd:dateTime as follows:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns4="http://www.optimiser.com/soap"
xmlns:ns5="urn:SOAPEchoDate"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns5:echoDate2Response>
<outDateWrap xsi:type="ns4:SOAPDateWrap">
<datefied xsi:type="xsd:dateTime">2004-05-14T10:21:18.6939682+08:00</datefied></outDateWrap></ns5:echoDate2Response>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Actual result:
--------------
The datefied member of the SOAPDateWrap complex type returned from the echoDate2() operation is of type xsd:string as follows:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns4="http://www.optimiser.com/soap"
xmlns:ns5="urn:SOAPEchoDate"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns5:echoDate2Response>
<outDateWrap xsi:type="ns4:SOAPDateWrap">
<datefied xsi:type="xsd:string">2004-05-14T10:21:18.6939682+08:00</datefied></outDateWrap></ns5:echoDate2Response>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
[2006-07-11 10:58 UTC] misc1 at elmerproductions dot com
I have the same problem with dateTime (and also had it with another type), so this is apparently still an issue in PEAR::SOAP version 0.9.4. However, there is a workaround by using the SOAP_Value class.
My type is an array of struct with several fields (a,b,c). Assume 'b' is the dateTime. To return this properly I use the following to define a single element of the array to return:
function get_element($aval,$bval,$cval)
{
return array(
'a'=>$aval, // simple value works automatically
'b'=>new SOAP_Value('b','dateTime',$bval), // more complex types need to use the SOAP_Value class
'c'=>$cval // simple value works automatically
);
}
When such an element is returned as response to a SOAP request, 'b' is properly returned as dateTime instead of string.