如何使用PHP对Ebay API进行soap调用?

时间:2016-10-01 17:40:56

标签: php api soap ebay

我想用肥皂打电话给eBay api并按关键字查找产品。在eBay documentation和其他在线资源的帮助下,我想出了这段代码:

$client = new \SoapClient('http://developer.ebay.com/webservices/finding/latest/FindingService.wsdl');
$soap_headers = array(
    new \SoapHeader('X-EBAY-SOA-OPERATION-NAME', 'findItemsByKeywords'),
    new \SoapHeader('X-EBAY-SOA-SERVICE-VERSION', '1.3.0'),
    new \SoapHeader('X-EBAY-SOA-REQUEST-DATA-FORMAT', 'XML'),
    new \SoapHeader('X-EBAY-SOA-GLOBAL-ID', 'EBAY-US'),
    new \SoapHeader('X-EBAY-SOA-SECURITY-APPNAME', '<there would be the key>'),
);
$client->__setSoapHeaders($soap_headers);

// Call wsdl function
$result = $client->__soapCall("findItemsByKeywords", array("keywords" => "Potter"));

但是,此代码会导致错误: “服务运营未知, 500内部服务器错误 - SoapFault“

我尝试将第一行更改为此(不知道为什么它应该有所作为,但我在某处看到了它):

$client = new \SoapClient(NULL, array(
"location" => 'http://svcs.sandbox.ebay.com/services/search/FindingService/v1', 
'uri' => 'http://svcs.sandbox.ebay.com/services/search/FindingService/v1')
);

现在导致此错误:缺少SOA操作名称标头, 500内部服务器错误 - SoapFault

有人知道导致这些错误的原因以及如何解决这些错误吗?

谢谢你,迈克!

2 个答案:

答案 0 :(得分:1)

以下代码有效。

define('APP_ID', '*** Your App ID ***');
$wsdl = 'http://developer.ebay.com/webservices/finding/latest/FindingService.wsdl';
// For sandbox
$endpoint_uri = 'http://svcs.sandbox.ebay.com/services/search/FindingService/v1';
// For production
//$endpoint_uri = 'http://svcs.ebay.com/services/search/FindingService/v1';

// We'll use this namespace explicitly for the 'keywords' tag,
// because the SoapClient doesn't apply it automatically.
$ns = 'http://www.ebay.com/marketplace/search/v1/services';
// The SOAP function
$operation = 'findItemsByKeywords';

$http_headers = implode(PHP_EOL, [
  "X-EBAY-SOA-OPERATION-NAME: $operation",
  "X-EBAY-SOA-SECURITY-APPNAME: " . APP_ID,
]);

$options = [
  'trace' => true,
  'cache' => WSDL_CACHE_NONE,
  'exceptions' => true,
  'location' => $endpoint_uri,
  //'uri' => 'ns1',
  'stream_context' => stream_context_create([
    'http' => [
      'method' => 'POST',
      'header' => $http_headers,
    ]
  ]),
];

$client = new \SoapClient($wsdl, $options);

try {
  $wrapper = new StdClass;
  $wrapper->keywords = new SoapVar('harry potter', XSD_STRING,
    null, null, null, $ns);

  $result = $client->$operation(new SoapVar($wrapper, SOAP_ENC_OBJECT));
  var_dump($result);
} catch (Exception $e) {
  echo $e->getMessage();
}

如前所述,其中一个问题是您将X-EBAY-SOA-*值作为 SOAP 标头传递。 service expects将其作为 HTTP 标题:

  

HTTP标头或网址参数 - 每次查找API调用都需要确定   HTTP标头或URL参数。例如,您必须指定您的   X-EBAY-SOA-SECURITY-APPNAME标题或SECURITY-APPNAME中的AppID   URL参数。同样,您必须始终在中指定呼叫名称   X-EBAY-SOA-OPERATION-NAME标头或OPERATION-NAME网址参数。   其他标题是可选的或有条件的。

第二个问题是未指定SoapClient location选项。它应该包含service endpoints之一的URI。否则,API会返回Service operation is unknown错误。

最后,SoapClient没有将keywords放入Ebay的命名空间中:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.ebay.com/marketplace/search/v1/services">
  <SOAP-ENV:Body>
    <ns1:findItemsByKeywordsRequest>
      <keywords>harry potter</keywords>
    </ns1:findItemsByKeywordsRequest>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

因此,API会返回错误:Keywords value required.。所以我明确地为keywords标签指定了名称空间。

还要注意使用不同的端点URI进行沙箱和生产。

答案 1 :(得分:0)

问题是,该服务需要 HTTP 标头(或查询字符串参数,显然,通过阅读他们的指南)。

使用__setSoapHeaders,您可以设置 SOAP 标题。

试试这个,例如

$wsdl = 'http://developer.ebay.com/webservices/finding/latest/FindingService.wsdl';

$appID = 'YOUR KEY/ID';

$headers = implode(PHP_EOL, [
  "X-EBAY-SOA-OPERATION-NAME: findItemsByKeywords",
  "X-EBAY-SOA-SECURITY-APPNAME: $appID"
]);

$options = [
  'trace' => true,
  'cache' => WSDL_CACHE_NONE,
  'exceptions' => true,
  'stream_context' => stream_context_create([
    'http' => [
      'header' => $headers
    ]
  ]),
];

$client = new SoapClient($wsdl, $options);

$response = $client->findItemsByKeywords([
  'keywords' => 'Potter'
]);