php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #50997 SOAP Error when trying to submit 2nd Element of a choice
Submitted: 2010-02-10 18:08 UTC Modified: 2012-09-03 08:09 UTC
Votes:37
Avg. Score:4.6 ± 0.8
Reproduced:32 of 34 (94.1%)
Same Version:6 (18.8%)
Same OS:7 (21.9%)
From: mrsharp at gmx dot de Assigned: dmitry
Status: Closed Package: SOAP related
PHP Version: 5.2.12 OS: debian
Private report: No CVE-ID:
 [2010-02-10 18:08 UTC] mrsharp at gmx dot de
Description:
------------
My Actual PHP Version: PHP Version 5.2.11-0.dotdeb.0

not 100% sure if this relates to Bug #43723: "SOAP not sent properly from client for <choice>" because SOAP is not sent at all in my scenario (Fatal Error)

Part of my WSDL is this schema excerpt

<xsd:complexType name="sometype">
  <xsd:choice>
   <xsd:group ref="sd:someGroupDefA"/>
   <xsd:group ref="sd:someGroupDefB"/>
  </xsd:choice> ....

A SOAP operation now employs this type... if I attempt to submit a property set which resembles "someGroupDefB" I receive a 

SOAP-ERROR: Encoding: object hasn't someGroupDefA property 

so it seems that choice is not properly evalutated...




Expected result:
----------------
I expect that SOAP accepts both sets of parameters without complaining about the other missing...


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-02-11 10:22 UTC] mrsharp at gmx dot de
Tested also using PHP Version 5.2.5-3 same result....
 [2010-07-13 12:56 UTC] sebastian at rootdir dot ws
As this still seems to be an issue, here is a complete reproducer:


$soapClient = new SoapClient('service2.wsdl', array ('trace' => 1));

$params = array('code' => 'foo');
$soapClient->newOperation($params);


WSDL excerpt:

<xsd:element name="NewOperation">
  <xsd:complexType>
   <xsd:choice>
     <xsd:sequence>
       <xsd:element name="firstName" type="xsd:string"> </xsd:element>
       <xsd:element name="surName" type="xsd:string"/>
     </xsd:sequence>
     <xsd:element name="code" type="xsd:string"/></xsd:choice>
  </xsd:complexType>
</xsd:element>

(You can find the whole WSDL example file over at http://pastebin.com/UZrPCuJt)


Actual result:

Fatal error: SOAP-ERROR: Encoding: object hasn't 'firstName' property


If you move element name "code" being the first child of <xsd:choice> the code snippet above is working as expected.
 [2011-05-17 11:09 UTC] yozik04 at gmail dot com
I can reproduce this with PHP version 5.3.5 in Ubuntu.

Moving element around in xsd is not a solution for me.

Is there any other workaround available without touching WSDL and XSD?
 [2012-04-11 11:34 UTC] christian dot achatz at payback dot net
This issue is also reproducable for PHP 5.3.8. It would be kind to fix it very soon.
 [2012-05-16 14:29 UTC] duccio at citta dot bo dot it
It's not really a solution to the bug, but it does make it work. In the passed 
parameters, define all the fields he's claiming as "Missing property".

So if you're using an array, and it says it's missing property 'GetData', do:

$requestArray['GetData'] = '';

and so on with each field, until it's working.
 [2012-05-24 12:20 UTC] potgieterg at gmail dot com
The above example of just putting empty strings for all the other choice fields is 
not working, sure it does not give you the error anymore but in my case the server 
is accepting the first choice as the choice even if I enter data for the second 
choice as well.
 [2012-07-20 13:33 UTC] jboffel at gmail dot com
Hi,

I'll give a try to help to solve that bug.

I think I identified the problem.

Algorythm for choice validation is : 

<xsd:choice>
     <xsd:sequence>
       <xsd:element name="firstName" type="xsd:string"> </xsd:element>
       <xsd:element name="surName" type="xsd:string"/>
     </xsd:sequence>
     <xsd:element name="code" type="xsd:string"/>
</xsd:choice>

- Enter choice element
- Take first sequence sub element
- Try to match list of elements against properties given to the function
- If fail (like in that example because we use element code instead of the sequence) => pass to second choice
- Try to match list of elements.......
- Success !
- return OK

And that is correctly implemented for what I saw in the soap_encoding.c file in source code of PHP extension.

However, I guess the problem is located in the part of the function analysing the node element of the chain.

If one of the mandatory parameters are note matched, that part of function will generate a php_error with E_ERROR severity level, I guess it's raising exception immediatly in the PHP engine and so it's stopping execution of the algorythm.

To try to solve partialy that problem, we can see that the strict parameter is set to 0 at sub call of model_to_xml_object from a choice segment.

case XSD_CONTENT_CHOICE: {
			sdlContentModelPtr *tmp;
			HashPosition pos;
			int ret = 0;

			zend_hash_internal_pointer_reset_ex(model->u.content, &pos);
			while (zend_hash_get_current_data_ex(model->u.content, (void**)&tmp, &pos) == SUCCESS) {
				int tmp_ret = model_to_xml_object(node, *tmp, object, style, 0 TSRMLS_CC);
				if (tmp_ret == 1) {
					return 1;
				} else if (tmp_ret != 0) {
					ret = 1;
				}
				zend_hash_move_forward_ex(model->u.content, &pos);
			}
			return ret;
		}

However, I think it is not enough, if choice content not only element but also sequence or list or union or any other groupment of element, it will pass the element in that group with it's normal strict level. Not with 0, so it will produce the error log raisin the exception.

Solution could be to try to propagate the strict property to 0 if coming from choice segment, but have to do that on all other segment of code for group type xml tag...

I succeed to confirm my theory by using same example than above but like that :

<xsd:element name="NewOperation">
  <xsd:complexType>
   <xsd:choice>
     <xsd:element name="code" type="xsd:string"/></xsd:choice>
     <xsd:sequence>
       <xsd:element name="firstName" type="xsd:string"> </xsd:element>
       <xsd:element name="surName" type="xsd:string"/>
     </xsd:sequence>
  </xsd:complexType>
</xsd:element>

$params = array('firstName' => 'foo', 'surName' => 'fooBar');
$soapClient->newOperation($params);

In that case, first iteration will pass the element without problem as the stric parameter has been forced to 0 and then when it will reach second iteration with the sequence it will match against our parameters.

So if you only have element in your choice or only element and at end something group type of element, it will work. Not if group type of element is somewhere else.

Reason is, I believe, because of group of elements are not type by themself. Sequence, union and list are not type. It doesn't make sense to pass them to srict or not strict in a choise case. When you make your array or parameters thoses levels dosen't appear. You don't need to create a key sequence to make it work. It's just usefull for schema interpretation.

It's leading me to other part of the problem. If we propagate strict value to 0 to each sub element of a sequence, it will obviously work, but will not really follow the schema as well. You could describe a schema with mandatory elements in a sequence even the sequence can be ignored by the choice legaly.

Exemple :

<xsd:choice>
     <xsd:sequence>
       <xsd:element name="firstName" type="xsd:string"> </xsd:element>
       <xsd:element name="surName" type="xsd:string"/>
     </xsd:sequence>
     <xsd:sequence>
       <xsd:element name="age" type="xsd:string" minOccurs="1"> </xsd:element>
       <xsd:element name="birthDate" type="xsd:string" minOccurs="0" />
     </xsd:sequence>
</xsd:choice>

You'd like to get an error if someone try to use the second choice and forget to put a paremeter age. It woudln't work if you propagate the strict parameter to value 0 to the element node matching...
It's meaning it is legal is this situation to fail to find a matching choice.

So, ultimately it's lead to only one real solution to my eyes. Create a way to disable the raise of php_error at element matching if we are in a choice process.
 [2012-08-02 14:04 UTC] dmitry@php.net
-Assigned To: +Assigned To: dmitry
 [2012-09-03 08:01 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@tpl2.home
Revision: http://git.php.net/?p=php-src.git;a=commit;h=485c09a3765b900aea182ddd2dded2286fb0749a
Log: Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice).
 [2012-09-03 08:01 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@tpl2.home
Revision: http://git.php.net/?p=php-src.git;a=commit;h=7e816c0921b4fee488d47b8a060ef820a7c46e38
Log: Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice)
 [2012-09-03 08:01 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@tpl2.home
Revision: http://git.php.net/?p=php-src.git;a=commit;h=0ab27c35a47901173f22d9e50ca75de0263c45a5
Log: Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice).
 [2012-09-03 08:01 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@tpl2.home
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2659f5e88e9e76594aff0d0c27500514dfef2cb2
Log: Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice)
 [2012-09-03 08:01 UTC] dmitry@php.net
Automatic comment on behalf of dmitry@tpl2.home
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4cca6241e03f0abd442fd867f397b14b3be9d0bd
Log: Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice)
 [2012-09-03 08:09 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2012-09-03 08:09 UTC] dmitry@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2013-11-17 09:32 UTC] laruence@php.net
Automatic comment on behalf of dmitry@tpl2.home
Revision: http://git.php.net/?p=php-src.git;a=commit;h=2659f5e88e9e76594aff0d0c27500514dfef2cb2
Log: Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice)
 [2013-11-17 09:32 UTC] laruence@php.net
Automatic comment on behalf of dmitry@tpl2.home
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4cca6241e03f0abd442fd867f397b14b3be9d0bd
Log: Fixed bug #50997 (SOAP Error when trying to submit 2nd Element of a choice)
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 17 09:02:29 2014 UTC