php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #50768 SoapClient parsing error on complex types
Submitted: 2010-01-15 14:54 UTC Modified: -
Votes:12
Avg. Score:4.8 ± 0.4
Reproduced:9 of 9 (100.0%)
Same Version:5 (55.6%)
Same OS:3 (33.3%)
From: alrik dot zachert at erento dot com Assigned:
Status: Open Package: SOAP related
PHP Version: 5.3.1 OS: Ubuntu 9.04
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: alrik dot zachert at erento dot com
New email:
PHP Version: OS:

 

 [2010-01-15 14:54 UTC] alrik dot zachert at erento dot com
Description:
------------
the native php soapclient throws a soapfault when passing complex types to a soap-service on php5.3.1 whereas php5.2.6-soapclient works correctly.

both, 5.3.1 and 5.2.6 ran on same machine with same modules enabled and almost same config.

the soapserver provides a test method that accepts exactly one parameter of type TestUser (see below) and returns the modified test object. 

I've tested the soapserver with soapUI and checked the wdsl, it 100%ly valid.

But the client on php5.3.1 troubles. See the actual soap-request (php5.3.1 vs. php5.2.6) below.

I guess it's a parsing error, but i couldn't find any hint in the releasenotes and changelogs.



You can also reproduce the bug??? by using Zend_Soap_Client, since it uses the native one. 

Reproduce code:
---------------
<?php /* soap client*/
    class TestUser {
        public $intUserId = 0;
        public $strName   = '';
    }

    $objUser = new TestUser;
    $sc = new SoapClient('path_to_wsdl' , array(
        'classmap' => array (
            'TestUser' => 'TestUser'
        )
    ));
    var_dump( $sc->test($objUser) );
?>

<?php /* soap server method */
    /**
     * @param TestUser $objUser the test user
     * @return TestUser $objUser the test user
     * @soap
     */
    public function test( TestUser $objUser )
    {
        $objUser->intUserId = 123456789;
        $objUser->strName = 'somename';
        return $objUser;
    }
?>

the wsdl: ==>

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" 
			 xmlns:tns="urn:SoaptestControllerwsdl" 
			 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
			 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
			 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
			 xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" 
			 name="SoaptestController" 
			 targetNamespace="urn:SoaptestControllerwsdl">
	<wsdl:types>
		<xsd:schema targetNamespace="urn:SoaptestControllerwsdl">
			<xsd:complexType name="TestUser">
				<xsd:all>
					<xsd:element name="intUserId" type="xsd:integer"/>
					<xsd:element name="strName" type="xsd:string"/>
				</xsd:all>
			</xsd:complexType>
		</xsd:schema>
	</wsdl:types>
	<wsdl:message name="testRequest">
		<wsdl:part name="objUser" type="tns:TestUser"/>
	</wsdl:message>
	<wsdl:message name="testResponse">
		<wsdl:part name="return" type="tns:TestUser"/>
	</wsdl:message>
	<wsdl:portType name="SoaptestControllerPortType">
		<wsdl:operation name="test">
			<wsdl:documentation/>
			<wsdl:input message="tns:testRequest"/>
			<wsdl:output message="tns:testResponse"/>
		</wsdl:operation>
	</wsdl:portType>
	<wsdl:binding name="SoaptestControllerBinding" type="tns:SoaptestControllerPortType">
		<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
		<wsdl:operation name="test">
			<soap:operation soapAction="urn:SoaptestControllerwsdl#test" style="rpc"/>
			<wsdl:input>
				<soap:body use="encoded" 
						   namespace="urn:SoaptestControllerwsdl" 
						   encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
			</wsdl:input>
			<wsdl:output>
				<soap:body use="encoded" 
						   namespace="urn:SoaptestControllerwsdl" 
						   encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
			</wsdl:output>
		</wsdl:operation>
	</wsdl:binding>
	<wsdl:service name="SoaptestControllerService">
		<wsdl:port name="SoaptestControllerPort" binding="tns:SoaptestControllerBinding">
			<soap:address location="http://localhost:81/yii/fTest/index.php/soaptest/test/ws/1"/>
		</wsdl:port>
	</wsdl:service>
</definitions>


Expected result:
----------------
the expacted service result:

object(TestUser)#3 (2) {
  ["intUserId"]=>
  int(123456789)
  ["strName"]=>
  string(8) "somename"
}

the expacted client-request :

...<SOAP-ENV:Body><ns1:test><objUser xsi:type="ns1:TestUser">...</objUser> ...



Actual result:
--------------
php5.3.1 =>

Fatal error: Uncaught SoapFault exception: [Client] looks like we got no XML document in /home/alrik/-:13
Stack trace:
#0 [internal function]: SoapClient->__call('test', Array)
#1 /home/alrik/-(13): SoapClient->test(Object(TestUser))
#2 {main}
  thrown in /home/alrik/- on line 13


php5.2.6 service result =>

object(TestUser)#3 (2) {
  ["intUserId"]=>
  int(123456789)
  ["strName"]=>
  string(8) "somename"
}


php5.3.1 client-request : 

...<SOAP-ENV:Body><ns1:test><param0 xsi:type="SOAP-ENC:Struct">..</param0>...

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-05-06 16:23 UTC] m dot breiner at brinell dot net
I'm experiencing a similar issue on PHP 5.3.6:
If a SOAP message refers to a complexType that is comprised of an xsd:all, PHP's SOAP implementation seems to require _all_ of the xsd:all's elements (which is not the idea of an xsd:all). I.e., when using e.g. a classmap, if such an element is not declared as a property, a SOAP error is thrown:

SOAP-ERROR: Encoding: object has no 'foo' property in...
 [2012-03-20 04:36 UTC] pkmishra at gmail dot com
Same problem on mac MAMP - PHP 5.3.6.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 16:01:31 2024 UTC