php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #33366 __soapCall Produces Incorrect Request
Submitted: 2005-06-16 18:44 UTC Modified: 2005-06-17 10:03 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: cmantunes at gmail dot com Assigned: dmitry (profile)
Status: Not a bug Package: SOAP related
PHP Version: 5.1.0 OS: Debian
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: cmantunes at gmail dot com
New email:
PHP Version: OS:

 

 [2005-06-16 18:44 UTC] cmantunes at gmail dot com
Description:
------------
When using SoapClient->__soapCall with parameters, the request  is incorrectly encoded regarding the method parameters. The first SoapParam is also ignored.

Reproduce code:
---------------
#!/usr/bin/php

<?php

  // AdWords API name space
  $ns="https://adwords.google.com/api/adwords/v2";

  // InfoService client
  $isc=new SoapClient($ns . '/InfoService?wsdl',
                      array('trace'=>1, 'exceptions'=>1)
                     );
  try
  {
    //
    // BUG: __soapCall *IGNORES* the first parameter!
    // That's why 'null' is being used
    //
    $params=array(null,
            new SoapParam('2005-04-01', 'startDate'),
            new SoapParam('2005-04-30', 'endDate'));

    //
    // BUG: This Call produces:
    // <ns1:getOperationCount/> ->CLOSED ALREADY!
    //   <startDate>2005-04-01</startDate>
    //   <endDate>2005-04-30</endDate>
    //
    $isc->__soapCall('getOperationCount', $params);
  }
  catch (Exception $e)
  {
    print_r($e);
  }

  print "Request:\n\n" .
    $isc->__getLastRequest() . "\n\n\n";
  print "Response:\n\n" .
    $isc->__getLastResponse() . "\n\n\n";

?>

Expected result:
----------------
<ns1:getOperationCount>
<startDate>2005-04-01</startDate>
<endDate>2005-04-30</endDate>
</ns1:getOperationCount>


Actual result:
--------------
<ns1:getOperationCount/>
<startDate>2005-04-01</startDate>
<endDate>2005-04-30</endDate>


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-06-16 18:56 UTC] sniper@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5-win32-latest.zip


 [2005-06-16 20:33 UTC] cmantunes at gmail dot com
As requested, I attempted the same code with the latest snapshot (php5-200506161630) but __soapCall continues to exhibit the same buggy behavior as before. As such, the problem doesn't appear to have been corrected yet. Thank you!
 [2005-06-17 10:03 UTC] dmitry@php.net
Hi,

The ext/soap is match easy in usage then you expected.
You should use the following code:

$isc->getOperationCount(array(
    'startDate' => '2005-04-01',
    'endDate'   => '2005-04-01'
  ));

or 

$isc->__soapCall('getOperationCount', array(
    array('getOperationCount' => array(
      'startDate' => '2005-04-01',
      'endDate'   => '2005-04-01'
  )));

You don't need to use SoapParam if you use WSDL.
 [2011-07-15 21:27 UTC] jonasraoni at gmail dot com
I have the same problem as "cmantunes" (I'm using an WSDL too), and many more at the same request.

#1. First argument being ripped off from the XML when calling directly ($client->method(args))

#2. After adding a bogus first parameter, the request got the method name closed and, the param was placed after it, just like the guy mentioned. And, also with the wrong name, the param should be "arg0" and it was displayed as "param1".

#3. Even after fixing the request, the response is also misunderstood by the extension! I had to make more workarounds to remove the trailing data (which seems to be part of a standard, the request works fine when I tested with the soapUI client):

--uuid:6365a322-9529-4cf5-b3bb-4ed69bd78b38
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <root.message@cxf.apache.org>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
[...]
--uuid:6365a322-9529-4cf5-b3bb-4ed69bd78b38--


#4. When using Apache 2.2.X on Windows and requesting a WSDL through HTTPS "new SoapClient" crashes Apache. It works fine just on IIS, I tested with several PHP versions and, also the latest (currently 5.3.6).

I had tried the suggested code by Dmitry before and it didn't work out.

Unhappily I made workarounds at the __doRequest to solve my immediate problems.
 [2011-07-30 14:31 UTC] jonasraoni at gmail dot com
Here are the fixes I had to make in order to get it working for *my* needs. I believe it will help the other users that had this problem (I found many cases on internet, but no fixes).

class FixedSOAPClient extends SoapClient{
	private $method;
	private $argumentCount;
	/*
	Loading the WSDL through PHP instead of letting the SoapClient do this job, avoids breaking Apache. I noticed it breaks just here, while loading the wsdl through *HTTPS*.
	Note: I believe that the __doRequest method should also be called when loading the .wsdl
	*/
	public function __construct($url){
		$s = file_get_contents($url);
		file_put_contents($url = md5($url) . '.wsdl', $s);
		parent::__construct($url, array(
			'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP
		));
	}
	public function __call($function, $arguments){
		$this->argumentCount = count($arguments);
		/*
		Adding a bogus parameter to the beginning, since the SoapClient is "eating" the first argument.
		*/
		array_unshift($arguments, 0);
		return parent::__call($this->method = $function, $arguments);
	}
	public function __doRequest($request, $location, $action, $version, $oneWay = 0){
		$xml = new DOMDocument('1.0', 'utf-8');
		$xml->loadXML($request);
		$d = $xml->documentElement;
		/*
		Placing the "lost" arguments inside the function node, their right place.
		*/
		for($o = $d->getElementsByTagName($this->method)->item(0); $o->nextSibling; $o->appendChild($o->nextSibling));

		$xml = $xml->saveXML();
		/*
		The operation expected parameters to be named as arg1, arg2, insted of what PHP built, which was param1, param2...
		*/
		if($this->argumentCount)
			foreach(range($this->argumentCount, 0) as $i)
				$xml = str_replace('param' . ($i + 1), 'arg' . $i, $xml);
		/*
		Removing boundary from the XML result, this must be part of a standard as the calls works fine on other tools, the SoapClient should be able to handle it.
		*/
		$s = preg_replace('/--.*?--$/', '', preg_replace('/^(?:.|\n|\r)*?<soap:/', '<soap:', parent::__doRequest($xml, $location, $action, $version, $oneWay)));
		return $s;
	}
}
 [2014-04-09 13:34 UTC] wtf dot stomp at gmail dot com
Fix it please!
 [2014-04-09 13:40 UTC] wtf dot stomp at gmail dot com
This bug described event there: http://www.php.net/manual/en/soapclient.soapcall.php#57032
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC