SOAP complex type extension issues

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

I am writing a SOAP interface for Zen Cart (based on osCommerce) to be released back to the community (backend to Java/.NET web-tier, anyone?). I am having issues with the PHP soap extension's schema/class mapping, namely inheritance. Your email addresses were listed in php_schema.c in the SOAP extension directory, so I figured you may be the people to ask; I apologize if you are not an appropriate person to contact about this issue. I've also CC'd this to the php.soap newsgroup.

My issue seems to be related to PHP bug #34218 (http://bugs.php.net/bug.php?id=34218); it involves compex type inheritance mapping to PHP classes. For example, my WSDL says return ShippingMethod, the function returns an instance of UpsShippingMethod which extends ShippingMethod both in code and in XSD, but the server returns ShippingMethod because WSDL says so (or faults if ShippingMethod is abstract). The correct behavior would be to check the type of the actual instance and make sure it is_a ShippingMethod and populate the complexType mapped to get_class.

I believe the modifications we are making would be very beneficial to PHP as an e-commerce, and webservice in general, platform. Unfortunately, this is a show stopping issue for this project (aside from gross hackery); what are the options for getting this issue resolved?

Thanks for your time,

Harlan Iverson
Plaudit Design, LLC


Here is simplified test code:


******************* test.php *******************
<?php


error_reporting( E_ALL );
ini_set( 'display_errors', true );
ini_set( 'short_open_tag', false );

//
// Setup the complex types and server
//

abstract class CT_A1 {
	public $var1;
}

class CT_A2 extends CT_A1 {
	public $var2;
}

class CT_A3 extends CT_A2 {
	public $var3;
}

class server {
	// returns A2 in WSDL
	function test( $a1 ) {
		$a3 = new CT_A3();
		$a3->var1 = $a1->var1;
		$a3->var2 = "var two";
		$a3->var3 = "var three";
		return $a3;
	}
}

$classMap = array( "A1" => "CT_A1", "A2" => "CT_A2", "A3" => "CT_A3" );

//
// Create the client and get the request to $soapRequest
//
$client = new SoapClient( "test.wsdl", array( "trace" => 1, "classmap" => $classMap ) );

$a2 = new CT_A2();
$a2->var1 = "one";
$a2->var2 = "two";
try {
	$client->test( $a2 );
} catch( Exception $e ) {

}

$soapRequest = $client->__getLastRequest();


//
// Create the server, handle the request in $soapRequest, and get the response to $soapResponse
//
$server = new SoapServer( "test.wsdl", array( "classmap" => $classMap ) );
$server->setClass( "server" );
ob_start();
$server->handle( $soapRequest );

$soapResponse = ob_get_contents();
ob_end_clean();


//
// Display the result
//
header( "Content-type: text/plain" );
header( "Content-length: " ); // SoapServer sets this, we we have to make it right
?>
================== Actual ==================
Request:
<?php echo $soapRequest; ?>


Response:
<?php echo $soapResponse; ?>


================== Expected ==================
Request:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"; xmlns:ns1="urn:test.soap#" xmlns:xsd="http://www.w3.org/2001/XMLSchema"; xmlns:ns2="urn:test.soap.types#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"; SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";><SOAP-ENV:Body><ns1:test><a1 xsi:type="ns2:A2"><var1 xsi:type="xsd:string">one</var1><var2 xsi:type="xsd:string">two</var2></a1></ns1:test></SOAP-ENV:Body></SOAP-ENV:Envelope>


Response:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"; xmlns:ns1="urn:test.soap#" xmlns:xsd="http://www.w3.org/2001/XMLSchema"; xmlns:ns2="urn:test.soap.types#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"; SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";><SOAP-ENV:Body><ns1:testResponse><result xsi:type="ns2:A3"><var1 xsi:type="xsd:string">one</var1><var2 xsi:type="xsd:string">var two</var2><var2 xsi:type="xsd:string">var three</var2></result></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>


******************* test.wsdl *******************
<?xml version="1.0" encoding="utf-8"?>
<definitions name="shoppingcart"
	xmlns="http://schemas.xmlsoap.org/wsdl/";
	xmlns:tns="urn:test.soap#" targetNamespace="urn:test.soap#"
	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/";
	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/";
	xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/";
	xmlns:xs="http://www.w3.org/2001/XMLSchema";
	
	xmlns:types="urn:test.soap.types#">
	<!-- all datatypes will be imported to namespace types: -->
	<types>
		<xs:schema
			targetNamespace="urn:test.soap#">

			<!-- this will import all types into this namespace -->
			<xs:import namespace="urn:test.soap.types#"
				schemaLocation="datatypes.xsd"/>
		</xs:schema>
	</types>
	
	
	<message name="test-request">
		<part name="a1" type="types:A1"/>
	</message>
	<message name="test-response">
		<part name="result" type="types:A2"/>
	</message>

	

	<portType name="catalog-porttype">
		<operation name="test" parameterOrder="a1">
			<input name="test-request" message="tns:test-request"/>
			<output name="test-response" message="tns:test-response"/>
		</operation>
	</portType>

	<!-- @type doesn't like tns: -->
	<binding name="catalog-binding" type="tns:catalog-porttype">
		<soap:binding style="rpc"
			transport="http://schemas.xmlsoap.org/soap/http"/>
		
		
		<operation name="test">
			<soap:operation soapAction="urn:test.soap#test"/>
			<input>
<soap:body use="encoded" namespace="urn:test.soap#" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
			</input>
			<output>
<soap:body use="encoded" namespace="urn:test.soap#" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
			</output>
		</operation>
	</binding>

	<service name="catalog">
		<!-- @binding doesn't like to be tns: -->
		<port name="catalog-port" binding="tns:catalog-binding">
			<soap:address location="xxxxxxxx"/>
		</port>
	</service>

</definitions>


******************* datatypes.xsd *******************

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema
	xmlns:xs="http://www.w3.org/2001/XMLSchema";
	xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/";
	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/";
	xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/";
	xmlns:tns="urn:test.soap.types#"
	targetNamespace="urn:test.soap.types#">

	<xs:complexType name="A1">
		<xs:all>
			<xs:element name="var1" type="xs:string" nillable="true"/>
		</xs:all>
	</xs:complexType>


	<xs:complexType name="A2">
		<xs:complexContent>
			<xs:extension base="tns:A1">
				<xs:all>
					<xs:element name="var2" type="xs:string" nillable="true"/>
				</xs:all>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
		

	 <xs:complexType name="A3">
		<xs:complexContent>
			<xs:extension base="tns:A2">
				<xs:all>
					<xs:element name="var3" type="xs:string" nillable="true"/>
				</xs:all>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
</xs:schema>

--
PHP Soap Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [PHP Users]     [Kernel Newbies]     [PHP Database]     [Yosemite]

  Powered by Linux