web服务-PHP SoapClient-未经授权的操作异常-请求格式正确


web services - PHP SoapClient - Unauthorized Operation Exception - Request formed properly?

我正在尝试访问第三方GPS跟踪SOAP WebService,以返回我们公司车辆的列表。我一直在查看SoapClient对象的文档,并在StackOverflow上阅读了许多示例,但我仍然不确定如何使此操作正常工作。

$api_key='xxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$service_url = http://api.remotehost.com/RemoteService.svc?wsdl

这是我试图访问的服务的WSDL,我试图访问GetVehicles()方法。当我使用创建新客户端时

$client=新SoapClient($service_url,array('cache_wsdl'=>0));

我能够运行$client->__getFunctions(),它正确地列出了服务的所有函数。然而,当我尝试使用以下方法访问GetVehicles时:

$vehicles=$client->GetVehicles($api_key);
var_dump($vehicles);

我收到一个"试图执行未经授权的操作"错误。我不确定这是否意味着请求的格式不正确,或者我访问的URL是否错误,或者到底发生了什么。我应该使用SoapClient的__soapCall或__doRequest方法访问它吗?如果您查看WSDL,您可以看到特定操作的其他操作URLS,我应该在某个地方使用它们吗?

为了尝试调试,我正在使用SoapUI程序。我在WSDL URL中输入,程序会拉入函数列表,我可以从那里发出请求。当我使用GetVehicles发出请求时,我会得到正确的列表结果,所以我知道不存在身份验证问题。

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:api="http://api.remotehost.com">
   <soapenv:Header/>
   <soapenv:Body>
      <api:GetVehicles>
         <!--Optional:-->
         <api:APIKey>xxxxxxxxxxxxxxxxxxxxxxxx</api:APIKey>
      </api:GetVehicles>
   </soapenv:Body>
</soapenv:Envelope>

它确实返回了正确的车辆文件列表XML。我很困惑我做错了什么,我没有时间完成这件事了。有人能帮我指明正确的方向,让我知道我应该如何发出这个SOAP请求吗?非常感谢您的帮助。非常感谢。

您需要指定如何使用$api_key值,如下所示:

$client->GetVehicles(array('APIKey' => $api_key));

为了补充一点解释,请致电此处:

$client->GetVehicles($api_key);

没有告诉客户端如何使用$api_key。如果你看一下__getFunctions()的输出,你会发现GetVehicles采用了某种类型的参数结构:

GetVehiclesResponse GetVehicles(GetVehicles $parameters)

要查看该参数结构是什么,您必须发出__getTypes()调用。这是相关线路:

struct GetVehicles { string APIKey; }

这意味着您想要传递GetVehicles调用的实际上是一个具有单个成员的结构。幸运的是,PHP很好,可以接受具有匹配名称的数组。

一个有用的调试方法是使用Fiddler作为调用的代理。(如果你不在Windows上,你可以用Wireshark做类似的事情。)加载Fiddler,然后像这样构建你的SoapClient:

$opts = array('proxy_host' => 'localhost', 'proxy_port' => 8888);
$client = new SoapClient($wsdl, $opts);

然后,你通过客户拨打的所有电话都会显示在Fiddler中供你检查。例如,您的原始呼叫在Fiddler中显示为:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:ns1="http://api.silentpassenger.com">
    <SOAP-ENV:Body>
        <ns1:GetVehicles/>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

看到你的APIKey元素不存在,可能会给你一个关于错误的有用线索。

试试这个:

$vehicles=$client->GetVehicles(array('APIKey' => $api_key));