php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73089 SOAP pass dictionary parameter
Submitted: 2016-09-15 13:33 UTC Modified: 2017-01-09 12:09 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: matteo dot veggia at gmail dot com Assigned: nikic (profile)
Status: Closed Package: SOAP related
PHP Version: 7.0.14 OS: Windows
Private report: No CVE-ID: None
 [2016-09-15 13:33 UTC] matteo dot veggia at gmail dot com
Description:
------------
I will be short: i have an WCF in a IIS Windows Server. This WCF host a web service with this function:

public Dictionary<string, string> TestRoutine(Dictionary<string, string> Data)

I calling this function with PHP with these rows:

$url = "http://testserver/test/test.svc?wsdl";
$soapClient = new SoapClient($url, array('cache_wsdl' => WSDL_CACHE_NONE) );
$argsSOAP = new StdClass();
$argsSOAP->Data = Array();
array_push($argsSOAP->Data, Array("Key"=>"A", "Value"=>"1"));
array_push($argsSOAP->Data, Array("Key"=>"B", "Value"=>"2"));
$resSOAP = $soapClient->TestRoutine($argsSOAP);
print_r($resSOAP);

In PHP 5.6.X these rows works! In PHP 7.0.11 NO! The "Data" parameter result empty

BUT

If I put the values into the dictionary with a direct assignment, not using "array_push":

$url = "http://testserver/test/test.svc?wsdl";
$soapClient = new SoapClient($url, array('cache_wsdl' => WSDL_CACHE_NONE) );
$argsSOAP = new StdClass();
$argsSOAP->Data = Array();
$argsSOAP->Data[0] = Array("Key"=>"A", "Value"=>"1");
$argsSOAP->Data[1] = Array("Key"=>"B", "Value"=>"2");
$resSOAP = $soapClient->TestRoutine($argsSOAP);
print_r($resSOAP);

IT WORKS!!! Why?
Can you check? My PHP application is all based with array_push. Please help
Thanks

Matteo V.

Test script:
---------------
$url = "http://testserver/test/test.svc?wsdl";
$soapClient = new SoapClient($url, array('cache_wsdl' => WSDL_CACHE_NONE) );
$argsSOAP = new StdClass();
$argsSOAP->Data = Array();
array_push($argsSOAP->Data, Array("Key"=>"A", "Value"=>"1"));
array_push($argsSOAP->Data, Array("Key"=>"B", "Value"=>"2"));
$resSOAP = $soapClient->TestRoutine($argsSOAP);
print_r($resSOAP);


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-09-15 13:38 UTC] nikic@php.net
-Status: Open +Status: Duplicate
 [2016-09-15 13:38 UTC] nikic@php.net
Duplicate of bug #71996, which will be fixed in PHP 7.0.12.
 [2016-10-17 07:57 UTC] requinix@php.net
-Status: Duplicate +Status: Re-Opened -PHP Version: 7.0.11 +PHP Version: 7.0.12
 [2016-10-17 07:57 UTC] requinix@php.net
Bug #73327 says this isn't resolved in 7.0.12.
 [2016-10-17 13:37 UTC] nikic@php.net
This is the param encoding I get on PHP 7.0.12:

         <param0 xsi:type="SOAP-ENC:Struct">
            <Data SOAP-ENC:arrayType="ns2:Map[2]" xsi:type="SOAP-ENC:Array">
               <item xsi:type="ns2:Map">
                  <item>
                     <key xsi:type="xsd:string">Key</key>
                     <value xsi:type="xsd:string">A</value>
                  </item>
                  <item>
                     <key xsi:type="xsd:string">Value</key>
                     <value xsi:type="xsd:string">1</value>
                  </item>
               </item>
               <item xsi:type="ns2:Map">
                  <item>
                     <key xsi:type="xsd:string">Key</key>
                     <value xsi:type="xsd:string">B</value>
                  </item>
                  <item>
                     <key xsi:type="xsd:string">Value</key>
                     <value xsi:type="xsd:string">2</value>
                  </item>
               </item>
            </Data>
         </param0>

Not knowing anything about SOAP specifically, it looks correct to me. Are you sure you are running PHP 7.0.12?
 [2016-10-17 14:42 UTC] matteo dot veggia at gmail dot com
Yeah, i'm running php 7.0.12 (phpinfo()... if you want more information tell me please).
Using the SoapClient::__getLastRequest() routine I have these results:

$soapClient->__getLastRequest()
Using array_push
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/"> <SOAP-ENV:Body> <ns1:TestRoutineDictionary> <ns1:Data/> </ns1:TestRoutineDictionary> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

Using index assign
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ns2="http://tempuri.org/"> <SOAP-ENV:Body> <ns2:TestRoutineDictionary> <ns2:Data> <ns1:KeyValueOfstringstring> <ns1:Key>A</ns1:Key> <ns1:Value>1</ns1:Value> </ns1:KeyValueOfstringstring> <ns1:KeyValueOfstringstring> <ns1:Key>B</ns1:Key> <ns1:Value>2</ns1:Value> </ns1:KeyValueOfstringstring> </ns2:Data> </ns2:TestRoutineDictionary> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

I think these informations can help you.
Best regards
Matteo V.
 [2016-10-18 12:59 UTC] matteo dot veggia at gmail dot com
I also tried the two methods with PHP version 5.6.9: the results are same:

<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ns2="http://tempuri.org/"> <SOAP-ENV:Body> <ns2:TestRoutineDictionary> <ns2:Data> <ns1:KeyValueOfstringstring> <ns1:Key>A</ns1:Key> <ns1:Value>1</ns1:Value> </ns1:KeyValueOfstringstring> <ns1:KeyValueOfstringstring> <ns1:Key>B</ns1:Key> <ns1:Value>2</ns1:Value> </ns1:KeyValueOfstringstring> </ns2:Data> </ns2:TestRoutineDictionary> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
 [2016-10-24 12:40 UTC] matteo dot veggia at gmail dot com
Any news? I need this fix...
 [2016-10-24 14:20 UTC] nikic@php.net
I just downloaded the PHP 7.0.12 NTS VC14 x64 build from http://windows.php.net/download/ and ran

    ./php.exe -dextension=`pwd`/ext/php_soap.dll test.php

Where test.php contains:

<?php

$client = new class(null, ['location' => '', 'uri' => 'http://example.org']) extends SoapClient {
    public function __doRequest($request, $location, $action, $version, $one_way = 0) {
        echo $request;
        return '';
    }
};
$argsSOAP = new StdClass();
$argsSOAP->Data = Array();
array_push($argsSOAP->Data, Array("Key"=>"A", "Value"=>"1"));
array_push($argsSOAP->Data, Array("Key"=>"B", "Value"=>"2"));
$client->TestRoutine($argsSOAP);

And received the output:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://example.org" xmlns:ns2="http://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:TestRoutine><param0 xsi:type="SOAP-ENC:Struct"><Data SOAP-ENC:arrayType="ns2:Map[2]" xsi:type="SOAP-ENC:Array"><item xsi:type="ns2:Map"><item><key xsi:type="xsd:string">Key</key><value xsi:type="xsd:string">A</value></item><item><key xsi:type="xsd:string">Value</key><value xsi:type="xsd:string">1</value></item></item><item xsi:type="ns2:Map"><item><key xsi:type="xsd:string">Key</key><value xsi:type="xsd:string">B</value></item><item><key xsi:type="xsd:string">Value</key><value xsi:type="xsd:string">2</value></item></item></Data></param0></ns1:TestRoutine></SOAP-ENV:Body></SOAP-ENV:Envelope>

Which is the expected output.

Which PHP build are you using? Is it a standard windows.php.net build or from some other packager? To preclude configuration problems, can you check what result you get when running directly from CLI (w/o server)?
 [2016-10-24 14:45 UTC] matteo dot veggia at gmail dot com
Your test works! 

is Apache environment?
I'm using Apache/2.4.23. What's your suggestions?
 [2016-10-24 14:58 UTC] matteo dot veggia at gmail dot com
I test with apache and php: 

with your test (with some updates):

<?php
$client = new class(null, ['location' => '', 'uri' => 'http://example.org', 'trace' => 1]) extends SoapClient {
    public function __doRequest($request, $location, $action, $version, $one_way = 0) {
        //echo $request;
        return '';
    }
};
$argsSOAP = new StdClass();
$argsSOAP->Data = Array();
array_push($argsSOAP->Data, Array("Key"=>"A", "Value"=>"1"));
array_push($argsSOAP->Data, Array("Key"=>"B", "Value"=>"2"));
$res = $client->TestRoutineDictionary($argsSOAP);
echo "REQUEST:<br>" . htmlspecialchars(str_ireplace('><', ">\n<", $client->__getLastRequest())) . "<br>";
?>

WORKS!!!!!

BUT

with "my" client:

<?php
$url = "http://mylink.org/myservice.svc?wsdl";
$client = new SoapClient($url, array('trace' => 1));
$argsSOAP = new StdClass();
$argsSOAP->Data = Array();
array_push($argsSOAP->Data, Array("Key"=>"A", "Value"=>"1"));
array_push($argsSOAP->Data, Array("Key"=>"B", "Value"=>"2"));
$res = $client->TestRoutineDictionary($argsSOAP);
echo "REQUEST:<br>" . htmlspecialchars(str_ireplace('><', ">\n<", $client->__getLastRequest())) . "<br>";
//echo "Response:<br>" . htmlspecialchars(str_ireplace('><', ">\n<", $client->__getLastResponse())) . "<br>";
?>

appears the problem:

<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/"> <SOAP-ENV:Body> <ns1:TestRoutineDictionary> <ns1:Data/> </ns1:TestRoutineDictionary> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

I await your response
 [2016-11-14 10:45 UTC] matteo dot veggia at gmail dot com
-PHP Version: 7.0.12 +PHP Version: 7.0.13
 [2016-11-14 10:45 UTC] matteo dot veggia at gmail dot com
The issue persists with PHP Version 7.0.13! I rewrite my code to remake the question simplified:

$url = "wwwp.example.com/hello.svc?wdsl";
$options = Array("trace"=>1);

//FIRST METHOD!!! (not working)
$soapClient = new SoapClient($url, $options);
$argsSOAP = new StdClass();
$argsSOAP->Data = Array();
array_push($argsSOAP->Data, Array("Key"=>"A", "Value"=>"1"));
array_push($argsSOAP->Data, Array("Key"=>"B", "Value"=>"2"));
$resSOAP = $soapClient->TestRoutineDictionary($argsSOAP);
echo "REQUEST:<br>" . htmlspecialchars(str_ireplace('><', ">\n<", $soapClient->__getLastRequest())) . "<br>";
echo "Response:<br>" . htmlspecialchars(str_ireplace('><', ">\n<", $soapClient->__getLastResponse())) . "<br>";

echo "\n\n<hr>\n\n";

//SECOND METHOD (working...)
$soapClient2 = new SoapClient($url, $options);
$argsSOAP2 = new StdClass();
$argsSOAP2->Data = Array();
$argsSOAP2->Data[0] = Array("Key"=>"A", "Value"=>"1");
$argsSOAP2->Data[1] = Array("Key"=>"B", "Value"=>"2");
$resSOAP2 = $soapClient2->TestRoutineDictionary($argsSOAP2);
echo "REQUEST:<br>" . htmlspecialchars(str_ireplace('><', ">\n<", $soapClient2->__getLastRequest())) . "<br>";
echo "Response:<br>" . htmlspecialchars(str_ireplace('><', ">\n<", $soapClient2->__getLastResponse())) . "<br>";

I execute this script with php.exe (without apache!)
The results are different!
In the first result is missing "http://schemas.microsoft.com/2003/10/Serialization/Arrays"...

Please help me.

Matteo
 [2016-12-02 12:49 UTC] matteo dot veggia at gmail dot com
-PHP Version: 7.0.13 +PHP Version: 7.1.0
 [2016-12-02 12:49 UTC] matteo dot veggia at gmail dot com
The problem persist.... Please help.
 [2016-12-04 15:43 UTC] sjon at hortensius dot net
@matteo - if the php.exe works then this is probably not a bug in php but in your apache configuration. You should verify what dll apache uses, check your configuration for the LoadModule call for php and make sure it looks like this:

LoadModule php7_module "c:/php/php7apache2.dll"

Obviously the php7apache2.dll you reference here should be 7.0.12 or higher. This is also explained in the "install.txt" that is in the file you download from http://windows.php.net/download
 [2016-12-05 07:27 UTC] matteo dot veggia at gmail dot com
@sjon: the problem persist without apache, executing manually in cmd the php.exe with a php test file.
Can you try this problem? Why you don't simulate it? It is easy, you need only an iis server, a simple wcf and the php code.
Am I the only person who has this problem?
 [2016-12-13 12:50 UTC] matteo dot veggia at gmail dot com
Same problem with PHP 7.0.14.
Have you tried my code? Have you the same problem?
 [2016-12-13 13:24 UTC] matteo dot veggia at gmail dot com
I've found another element which it can explain more considerations:
If I use

$argsSOAP->Data = Array();
array_push($argsSOAP->Data, Array("Key"=>"A", "Value"=>"1"));
array_push($argsSOAP->Data, Array("Key"=>"B", "Value"=>"2"));
$resSOAP = $soapClient->TestRoutineDictionary($argsSOAP);

the XML is wrong (read last posts). 
BUT... if I use a "support" variable called "tmparr":

$tmparr = Array();
array_push($tmparr, Array("Key"=>"A", "Value"=>"1"));
array_push($tmparr, Array("Key"=>"B", "Value"=>"2"));
$argsSOAP->Data = $tmparr;
$resSOAP = $soapClient->TestRoutineDictionary($argsSOAP);

IT WORKS!!!

Simple question... why?
 [2016-12-13 17:02 UTC] nikic@php.net
-Status: Re-Opened +Status: Feedback
 [2016-12-13 17:02 UTC] nikic@php.net
I've applied a few more fixes in https://github.com/php/php-src/commit/4b2cc62e266cb39d0728dc473435fdf6ab4e8e89, based on guesswork as to where the issue might be. Can you please test a snapshot build (http://windows.php.net/snapshots/ from tomorrow) to see if the issue is resolved?
 [2016-12-16 14:51 UTC] matteo dot veggia at gmail dot com
-Status: Feedback +Status: Open
 [2016-12-16 14:51 UTC] matteo dot veggia at gmail dot com
@nikic: With what snapshot?
 [2016-12-16 21:10 UTC] nikic@php.net
Any one of the snapshot builds for 7.0, 7.1 or master should do. Doesn't matter which one you use.
 [2016-12-19 12:42 UTC] matteo dot veggia at gmail dot com
PHP 7.0.14: The bug is still here
PHP 7.1: IT WORKS!!!!!!!!!!!!!!!!!!

Then can you check in 7.0.14?
 [2016-12-21 10:03 UTC] matteo dot veggia at gmail dot com
-PHP Version: 7.1.0 +PHP Version: 7.0.14
 [2016-12-21 10:03 UTC] matteo dot veggia at gmail dot com
Can you fix 7.0.14? I cannot use 7.1 because some extensions (sqlsrv) are not updated. Thanks!
 [2016-12-21 20:33 UTC] nikic@php.net
To clarify, you're saying that the PHP 7.1 snapshot build works, but the PHP 7.0 snapshot does not? That's odd, because the change is in both branches.
 [2016-12-22 07:00 UTC] matteo dot veggia at gmail dot com
Correct. 7.0.14 doesn't work. I download this version:

http://windows.php.net/downloads/releases/php-7.0.14-Win32-VC14-x64.zip

Files in zip are modified in 6 Dec 2016. Please check.
Thanks!
 [2017-01-09 07:32 UTC] matteo dot veggia at gmail dot com
Hello and happy new year!!!
Have you checked the 7.0.14?
In the 7.1 the routine works!
 [2017-01-09 10:45 UTC] nikic@php.net
-Status: Open +Status: Feedback
 [2017-01-09 10:45 UTC] nikic@php.net
There is a 7.0.15RC1 release (see http://windows.php.net/qa/) now which contains this fix. Can you please check it?
 [2017-01-09 11:28 UTC] matteo dot veggia at gmail dot com
-Status: Feedback +Status: Open
 [2017-01-09 11:28 UTC] matteo dot veggia at gmail dot com
FINALLY! With version 7.0.15RC IT WORKS!
Last question: when will be released 7.0.15 version? XD
 [2017-01-09 12:09 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2017-01-09 12:09 UTC] nikic@php.net
Thanks for verifying! I don't know the exact release date, but it will be approximately two weeks from now.
 [2017-05-31 12:48 UTC] wapinet at mail dot ru
php code:
$server = new SoapServer('my.wsdl');
$server->setClass(Api::class);
$server->handle();

class Api
{
    public function receiveEDIMessages()
    {
        return array(
            'head' => null,
            'body' => array(
                'message' => 'text',
                'from' => '2352457999993',
                'to' => '2352456999994',
                'id' => 54370
            ),
        );
    }
}


WSDL (use rpc style):
<xsd:complexType name="bodyMessagesResponse">
	<xsd:complexContent>
		<xsd:restriction base="soapenc:Array">
			<xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="tns:messageResponse[]"/>
		</xsd:restriction>
	</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="messageResponse">
	<xsd:sequence>
		<xsd:element name="message" type="xsd:string"/>
		<xsd:element name="from" type="xsd:string"/>
		<xsd:element name="to" type="xsd:string"/>
		<xsd:element name="id" type="xsd:integer"/>
	</xsd:sequence>
</xsd:complexType>


response php 5.6:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http_://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http_://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:interface" xmlns:xsd="http_://www.w3.org/2001/XMLSchema" xmlns:xsi="http_://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="urn:private" xmlns:SOAP-ENC="http_://schemas.xmlsoap.org/soap/encoding/">
   <SOAP-ENV:Body>
      <ns1:receiveEDIMessagesResponse>
         <receiveEDIMessagesReturn xsi:type="ns2:receiveEDIMessagesResponse">
            <head xsi:type="ns2:headResponse">
               <code xsi:type="xsd:int">0</code>
               <message xsi:nil="true"/>
            </head>
            <body SOAP-ENC:arrayType="ns2:messageResponse[1]" xsi:type="ns2:bodyMessagesResponse">
               <item xsi:type="ns2:messageResponse">
                  <message xsi:type="xsd:string">text</message>
                  <from xsi:type="xsd:string">2352457999993</from>
                  <to xsi:type="xsd:string">2352456999994</to>
                  <id xsi:type="xsd:integer">54370</id>
               </item>
            </body>
         </receiveEDIMessagesReturn>
      </ns1:receiveEDIMessagesResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>


response php 7.x:
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http_://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http_://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:interface" xmlns:xsd="http_://www.w3.org/2001/XMLSchema" xmlns:xsi="http_://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="urn:private" xmlns:ns3="http_://xml.apache.org/xml-soap" xmlns:SOAP-ENC="http_://schemas.xmlsoap.org/soap/encoding/">
   <SOAP-ENV:Body>
      <ns1:receiveEDIMessagesResponse>
         <receiveEDIMessagesReturn xsi:type="ns2:receiveEDIMessagesResponse">
            <head xsi:type="ns2:headResponse">
               <code xsi:type="xsd:int">0</code>
               <message xsi:nil="true"/>
            </head>
            <body SOAP-ENC:arrayType="ns3:Map[1]" xsi:type="ns2:bodyMessagesResponse">
               <item xsi:type="ns3:Map">
                  <item>
                     <key xsi:type="xsd:string">message</key>
                     <value xsi:type="xsd:string">text</value>
                  </item>
                  <item>
                     <key xsi:type="xsd:string">from</key>
                     <value xsi:type="xsd:string">2352457999993</value>
                  </item>
                  <item>
                     <key xsi:type="xsd:string">to</key>
                     <value xsi:type="xsd:string">2352456999994</value>
                  </item>
                  <item>
                     <key xsi:type="xsd:string">id</key>
                     <value xsi:type="xsd:string">54370</value>
                  </item>
               </item>
            </body>
         </receiveEDIMessagesReturn>
      </ns1:receiveEDIMessagesResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
 [2017-05-31 14:27 UTC] wapinet at mail dot ru
!!!
problem only if SoapServer configured with "'cache_wsdl' => WSDL_CACHE_MEMORY"
!!!
if "'cache_wsdl' => WSDL_CACHE_DISK" or none the problem is not reproduced (works correct).

P.S.: correct php code from prev message:

class Api
{
    public function receiveEDIMessages()
    {
        return array(
            'head' => null,
            'body' => array(array(
                'message' => 'text',
                'from' => '2352457999993',
                'to' => '2352456999994',
                'id' => 54370
            )),
        );
    }
}
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat Dec 14 18:01:24 2019 UTC