为啥 SOAP 参数的顺序在 PHP SOAP 中很重要,以及如何解决它?
Posted
技术标签:
【中文标题】为啥 SOAP 参数的顺序在 PHP SOAP 中很重要,以及如何解决它?【英文标题】:Why does the order of SOAP parameters matter in PHP SOAP, and how to fix it?为什么 SOAP 参数的顺序在 PHP SOAP 中很重要,以及如何解决它? 【发布时间】:2010-11-19 05:20:21 【问题描述】:php 手册中的A comment 声明:
如果您使用此方法,请记住 参数数组需要是 传入的顺序是 与 SOAP 端点相同的顺序 预计。
例如 //服务器期望:Foo(string name, int age)
//won't work $args = array(32, 'john'); $out = $client->__soapCall('Foo', $args); //will work $args = array('john', 32); $out = $client->__soapCall('Foo', $args);
我正在构建一个动态分配参数值的 SOAP 客户端,这意味着参数的顺序并不总是正确的。这会中断实际的 SOAP 调用。
除了检查每个调用的参数顺序之外,有没有简单的解决方案?
【问题讨论】:
【参考方案1】:我在动态添加 SOAP 参数时遇到了同样的问题,我必须以正确的顺序获取它们才能使我的 SOAP 调用正常工作。
所以我必须编写一些东西来从 WSDL 中获取所有 SOAP 方法,然后确定方法参数的排列顺序。
幸运的是,PHP 使用 '$client->__getFunctions()' 方法可以轻松获取 SOAP 函数,因此您需要做的就是搜索要调用的服务方法,该方法将包含正确的顺序,然后进行一些数组匹配以使您的请求参数数组以相同的顺序。
这里是代码...
<?php
// Instantiate the soap client
$client = new SoapClient("http://localhost/magento/api/v2_soap?wsdl", array('trace'=>1));
$wsdlFunctions = $client->__getFunctions();
$wsdlFunction = '';
$requestParams = NULL;
$serviceMethod = 'catalogProductInfo';
$params = array('product'=>'ch124-555U', 'sessionId'=>'eeb7e00da7c413ceae069485e319daf5', 'somethingElse'=>'xxx');
// Search for the service method in the wsdl functions
foreach ($wsdlFunctions as $func)
if (stripos($func, "$serviceMethod(") !== FALSE)
$wsdlFunction = $func;
break;
// Now we need to get the order in which the params should be called
foreach ($params as $k=>$v)
$match = strpos($wsdlFunction, "\$$k");
if ($match !== FALSE)
$requestParams[$k] = $match;
// Sort the array so that our requestParams are in the correct order
if (is_array($requestParams))
asort($requestParams);
else
// Throw an error, the service method or param names was not found.
die('The requested service method or parameter names was not found on the web-service. Please check the method name and parameters.');
// The $requestParams array now contains the parameter names in the correct order, we just need to add the values now.
foreach ($requestParams as $k=>$paramName)
$requestParams[$k] = $params[$k];
try
$test = $client->__soapCall($serviceMethod, $requestParams);
print_r($test);
catch (SoapFault $e)
print_r('Error: ' . $e->getMessage());
【讨论】:
【参考方案2】:命名参数有一个简单的解决方案:
function checkParams($call, $parameters)
$param_template = array(
'Foo' => array('name', 'age'),
'Bar' => array('email', 'opt_out'),
);
//If there's no template, just return the parameters as is
if (!array_key_exists($call, $param_template))
return $parameters;
//Get the Template
$template = $param_template[$call];
//Use the parameter names as keys
$template = array_combine($template, range(1, count($template)));
//Use array_intersect_key to filter the elements
return array_intersect_key($parameters, $template);
$parameters = checkParams('Foo', array(
'age' => 32,
'name' => 'john',
'something' => 'else'
));
//$parameters is now array('name' => 'john', 'age' => 32)
$out = $client->__soapCall('Foo', $parameters);
它不仅对参数进行正确排序,还对数组中的参数进行过滤。
【讨论】:
【参考方案3】:另一个解决方案是验证来自 wsdl 的 xsd 文件。 PHP SOAP 根据 xsd 文件中的参数顺序构造请求。
【讨论】:
以上是关于为啥 SOAP 参数的顺序在 PHP SOAP 中很重要,以及如何解决它?的主要内容,如果未能解决你的问题,请参考以下文章
关于 php 调用 其他语言写的Web Service SOAP 接口的参数传递问题
json PHP服务中的SOAP服务在PHP中的SOAP客户端 - http://www.starstormdesign.de/soap-service-mit-einem-soap-client-