|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[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> PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Nov 21 08:00:01 2025 UTC |
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.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; } }