Call us Toll-Free:
1-800-218-1525
Live ChatEmail us

 Sponsors

PHP4 Pear/SOAP document-style bug fix

omri schwartz, 02-15-2009
Working on integrating with Microsoft AdCenter API, I encountered a problem with the body section of the soap message.

Took a while to figure this one, so I figured I will share my findings.

Microsoft AdCenter offers a Pear/SOAP API. Pear/SOAP has two modes: 'RPC' or 'Document'.

The IBM site has a great article about the difference between RPC and Document-style web services.

In this case Microsoft AdCenter is using the 'Document' style. Integration with PHP5 built-in SOAP support, went through without any issues. But I had to get this working with PHP4.

Seems like PHP4 SOAP doesn't support the 'Document' style.

The body section of wsdl of this web service is as following:


<s:Body>
  <
GetCampaignsByAccountIdRequest
  xmlns
="https://adcenter.microsoft.com/api/advertiser/v5">
  <
AccountId>XXXXX</AccountId>
  </
GetCampaignsByAccountIdRequest>
</
s:Body>

The PHP parameter for this request should be:

$param
=
Array(
'GetCampaignsByAccountIdRequest'=>array('AccountId'=>XXXXX));

When trying to send this parameter, I kept receiving an error from SOAP_Client object, saying :

The named parameter AccountId is not in the call parameters.

Reviewing SOAP_client code:

function _generate($method, $params, $namespace = false,
         
$soapAction = false)

if (isset(
$params[$name]) ||
$this->_wsdl->getDataHandler($name, $part['namespace']))
{
   
$nparams[$name] =& $params[$name];
}
else
{
 
// We now force an associative array for
  // parameters if using WSDL.
 
return $this->_raiseSoapFault("The named parameter $name is
      not in the call parameters."
);
}

Notice the SOAP_Client method is looking for the parameters in the first dimension of the parameters array.

So I tried the following parameter:

$param
= array('AccountId'=>XXXXX);

No error, but the request ends up looking like this:

<s:Body>
  <
GetCampaignsByAccountId
  xmlns
="https://adcenter.microsoft.com/api/advertiser/v5">
  <
AccountId>XXXXX</AccountId>
  </
GetCampaignsByAccountId>
</
s:Body>

And Microsoft AdCenter server returns:
OperationFormatter encountered an invalid Message body. Expected to find node type 'Element' with name 'GetCampaignsByAccountIdRequest' Found node type 'Element' with name 'GetCampaignsByAccountId'.

The Problem

SOAP_Client wraps the parameter with the action name ('rpc' style).

According to pear.php.net, setting the style to 'document' should fix this.

Unfortunately, it doesn't work.

Solution

The most simple thing in this case is to set the body section as XML string parameter, but SOAP_Client class doesn't have this option. Here's how I fixed it:

Wrote a new class that inherits from SOAP_Client, overriding 2 methods:


class SOAP_Client_ex extends SOAP_Client
 
function _generate($method, $params, $namespace = false,
         
$soapAction = false)
  function
makeEnvelope($method, $headers, $encoding =         
         
SOAP_DEFAULT_ENCODING, $options = array())

I've copied these functions as is from the base classes.
In override function SOAP_Client_ex->_generate, I made sure it doesn't try to serialize the parameters by changing this:

 
//$this->_options['input'] = 'parse';
   
$this->_options['input'] = 'dontparse';

In override function SOAP_Client_ex->makeEnvelope, there was already a section for not serializing:

if (!isset($options['input']) || $options['input'] == 'parse')
// some code
else
{
 
// $smsg = $method
 
$smsg = $method['bodytext']; // use xml message as is
}

Had to change it a little because $method is an array, so I specified


$smsg
= $method['bodytext'].

Last step is changing the call parameters to xml:


// set parameters as xml
$paramText ='
<GetCampaignsByAccountIdRequest
xmlns="https://adcenter.microsoft.com/api/advertiser/v5">
  <AccountId>'
.$accountId.'</AccountId>
</GetCampaignsByAccountIdRequest>'
;
       
$result = $client->call(
     
'GetCampaignsByAccountId',
      array(
'bodytext'=>$paramText),
      array(
'trace'=>true));

And voila! All is well.

Is this a bug in PHP4 Pear/SOAP implementation?

Please reply to this post and let me know your thoughts.

SeanJA, 02-26-2009
Have you tried PHP 5?

Dawn Rossi, 02-26-2009
Hi Sean,

Yes - works without any issues with PHP5.

But we had to get it working with PHP4. This is a fix for PHP4 Pear/SOAP lack of support for the 'document' style.
Enjoyed this post?

Subscribe Now to receive new posts via Email as soon as they come out.

 Comments
Post your comments












Note: No link spamming! If your message contains link/s, it will NOT be published on the site before manually approved by one of our moderators.



About Us  |  Contact us  |  Privacy Policy  |  Terms & Conditions