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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
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: Fri Dec 27 06:01:29 2024 UTC