php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #31727 SOAPClient incorrectly encoding parameters
Submitted: 2005-01-27 19:55 UTC Modified: 2005-01-31 19:00 UTC
From: adam at trachtenberg dot com Assigned: dmitry (profile)
Status: Not a bug Package: SOAP related
PHP Version: 5CVS-2005-01-27 (dev) OS: n/a
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: adam at trachtenberg dot com
New email:
PHP Version: OS:

 

 [2005-01-27 19:55 UTC] adam at trachtenberg dot com
Description:
------------
The SOAPClient class is incorrectly encoding parameters. It is not placing them inside their own named elements.

I believe this to be a bug, but it's quite hard to confirm because the SOAP spec is so theoretical. I can't find any real examples. Also, even after this bug is fixed, the "working" code won't make a successful request, as the WSDL endpoint is wrong and there are no headers. This is just a stripped down version to reproduce the bug.

Reproduce code:
---------------
$wsdl_url = 'http://developer.ebay.com/webservices/393/eBaySvc.wsdl';

$client = new SOAPClient($wsdl_url, array('trace' => 1, 'exceptions' => 0, )); 

$DetailLevel = new SOAPParam(new SOAPVar('ReturnAll', XSD_STRING,  NULL, NULL, NULL, 'urn:ebay:apis:eBLBaseCo\
mponents'), 'DetailLevel');
$Version     = new SOAPParam(new SOAPVar(393,         XSD_DOUBLE, NULL, NULL, NULL, 'urn:ebay:apis:eBLBaseCom\
ponents'), 'Version');

$user = $client->GetUser($Version, $DetailLevel);
print "GetUser(): \n".$client->__getLastRequest() ."\n";

$user = $client->__call('GetUser', array($Version, $DetailLevel));
print "__call(GetUser): \n".$client->__getLastRequest() ."\n";

Expected result:
----------------
GetUser(): 
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:ebay:apis:eBLBaseComponents"><SOAP-ENV:Body><ns1:GetUserRequest><ns1:Version>393</ns1:Version><ns1:DetailLevel>ReturnAll</ns1:DetailLevel></ns1:GetUserRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>

__call(GetUser): 
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:ebay:apis:eBLBaseComponents"><SOAP-ENV:Body><ns1:GetUserRequest><ns1:Version>393</ns1:Version><ns1:DetailLevel>ReturnAll</ns1:DetailLevel></ns1:GetUserRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>

Actual result:
--------------
GetUser(): 
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:ebay:apis:eBLBaseComponents"><SOAP-ENV:Body><ns1:GetUserRequest>393</ns1:GetUserRequest><ns1:DetailLevel>ReturnAll</ns1:DetailLevel></SOAP-ENV:Body></SOAP-ENV:Envelope>

__call(GetUser): 
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:ebay:apis:eBLBaseComponents"><SOAP-ENV:Body><ns1:GetUserRequest>393</ns1:GetUserRequest><ns1:DetailLevel>ReturnAll</ns1:DetailLevel></SOAP-ENV:Body></SOAP-ENV:Envelope>

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-01-28 11:38 UTC] dmitry@php.net
ext/soap is more simple in use then you think, but it requre some understanding of SOAP encoding.

The following code should work fine.

<?php

$wsdl_url = 'http://developer.ebay.com/webservices/393/eBaySvc.wsdl';

$client = new SOAPClient($wsdl_url, 
                         array('trace' => 1, 'exceptions' => 0)); 

$user = $client->GetUser(array('Version'=>393, 
                               'DetailLevel'=>'ReturnAll', 
                               'UserID'=>'?'));
print "GetUser(): \n".$client->__getLastRequest() ."\n";
print "GetUser(): \n".$client->__getLastResponse() ."\n";

?>


 [2005-01-28 18:29 UTC] adam at trachtenberg dot com
Unfortunately, eBay's SOAP is more complex than this. I actually need to send SOAP headers, so I cannot use the simplified call format. Here what I actually need to do:

$token = 'TTT';
$devId = 'DDD';
$appId = 'AAA';
$certId = 'CCC';

$wsdl_url = 'http://developer.ebay.com/webservices/393/eBaySvc.wsdl';
$client = new SOAPClient($wsdl_url, array('trace' => 1, 'exceptions'
=> 0, ));

class eBayAuth {
        function __construct($token, $dev, $app, $cert) {
                $credentials = new eBayCredentials($dev, $app, $cert);
                $this->eBayAuthToken = new SoapVar($token, XSD_STRING, NULL, NULL, NULL, 'urn:ebay:apis:eBLBaseComponents');
                $this->Credentials = new SoapVar($credentials, SOAP_ENC_OBJECT, NULL, NULL, NULL, 'urn:ebay:apis:eBLBaseComponents');
        }
}

class eBayCredentials {
        function __construct($dev, $app, $cert) {
                $this->AppId   = $app;
                $this->DevID   = $dev;
                $this->AuthCert  = $cert;
        }
}

$eBayAuth = new eBayAuth($token, $devId, $appId, $certId);
$header_body = new SoapVar($eBayAuth, SOAP_ENC_OBJECT);

$header = array(new SOAPHeader('urn:ebay:api:eBLBaseComponents', 'RequesterCredentials', $header_body));

$params = array('Version' => 393, 'DetailLevel' => 'ReturnAll');

$user = $client->__call('GetUser', $params, NULL, $header);

This generates:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:ebay:apis:eBLBaseComponents" xmlns:ns2="urn:ebay:api:eBLBaseComponents"><SOAP-ENV:Header><ns2:RequesterCredentials><ns1:eBayAuthToken>TTT</ns1:eBayAuthToken><ns1:Credentials><AppId>AAA</AppId><DevID>DDD</DevID><AuthCert>CCC</AuthCert></ns1:Credentials></ns2:RequesterCredentials></SOAP-ENV:Header><SOAP-ENV:Body><ns1:GetUserRequest/><param1>ReturnAll</param1></SOAP-ENV:Body></SOAP-ENV:Envelope>

As you can see, now the parameters are totally incorrect. One is missing. The other is called "param1".

My header construction may be overly complex; however, our SOAP service recently switched from 3 namespaces to 1 namespace. When there were 3 namespaces, I found I needed to manually set the values because otherwise they would not be inside the correct namespace. (Actually, looking at this, I may still need to place additional fields inside the namespace.)

This problem would go away if ext/soap supported the instantiation of the complexTypes defined in the WSDL, the ability to set their values, and then pass those objects into the SOAPClient, but I realize that's a non-trivial job.
 [2005-01-31 09:01 UTC] dmitry@php.net
As I understand this Web Service uses document encoding and the 'GetUser' method uses one argument of complexType.
So you should call it in the following way.

$params = array('Version' => 393, 'DetailLevel' => 'ReturnAll');

$user = $client->__soapCall('GetUser', array($params), NULL, $header);

 [2005-01-31 19:00 UTC] amt@php.net
Yup. That seems to work. Sorry for the noise.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 01:01:30 2024 UTC