php soap客户端,错误wsdl导致的错误&引用;未捕获的SoapFault异常:[HTTP]无法连接到主机";

php soap客户端,错误wsdl导致的错误&引用;未捕获的SoapFault异常:[HTTP]无法连接到主机";,php,soap,wsdl,Php,Soap,Wsdl,我对SOAP基本上是新手,所以我制作了一个小测试脚本来连接到我客户的服务器。其中有一个GetMessage命令,不需要输入或身份验证,仅用于测试连接性: <?php ini_set('soap.wsdl_cache_enabled',0); ini_set('soap.wsdl_cache_ttl',0); $url = "https://test.mycustomer.com/api/TestService.svc?wsdl"; $client = new Soa

我对SOAP基本上是新手,所以我制作了一个小测试脚本来连接到我客户的服务器。其中有一个GetMessage命令,不需要输入或身份验证,仅用于测试连接性:

<?php
ini_set('soap.wsdl_cache_enabled',0);
ini_set('soap.wsdl_cache_ttl',0);

$url        = "https://test.mycustomer.com/api/TestService.svc?wsdl";
$client     = new SoapClient($url, array("trace" => 1, "exception" => 0));

$result = $client->GetMessage(NULL);

echo "<pre>".print_r($result, true)."</pre>";
if($result->GetMessageResult->Status == "Success")
{
    echo "Item deleted!";
}
?>
在该服务的WSDL中,字符串“459265”出现在此处:

array(2) {
  [0]=>
  string(53) "GetMessageResponse GetMessage(GetMessage $parameters)"
  [1]=>
  string(53) "GetMessageResponse GetMessage(GetMessage $parameters)"
}
array(5) {
  [0]=>
  string(21) "struct GetMessage {
}"
  [1]=>
  string(55) "struct GetMessageResponse {
 string GetMessageResult;
}"
  [2]=>
  string(8) "int char"
  [3]=>
  string(17) "duration duration"
  [4]=>
  string(11) "string guid"
}

您要做的是将代码包装在
try{},catch{}
块中。比如说,

class MySoapClient extends SoapClient
{
    public function __doRequest($request, $location, $action, $version, $one_way = 0)
    {
        $response = parent::__doRequest($request, "https://test.mycustomer.com/api/TestService.svc", $action, $version, $one_way);

        return($response);
    }
}


正如错误所说,
致命错误:未捕获的SoapFault异常:[HTTP]无法连接到..
中的主机,因此在任何情况下都需要捕获异常。希望这能有所帮助。

部分解决了这个问题。问题出在wsdl服务声明中,它有两个端口用于相同的绑定(见上文)。在php的SoapClient中,_doRequest的$location来自第一个绑定(如果我使用了错误的术语,请原谅),而该绑定的url是我无法访问的本地url。所以我这样做了:


扩展SoapClient并覆盖_udorequest,我能够将$location设置为我知道可以使用的url。再次运行它并收到欢迎信息-yipee!这不是一个很好的解决方案,因为我必须为每个服务扩展一个新的客户端,但要解决这个问题,我所要做的就是取出硬编码的url,用外部域替换$location中的本地域,然后用它调用u doRequest,它将与所有服务一起工作。

听起来像是一个问维护该WSDL的人的问题,但我肯定认为您已经发现了问题。我补充说,谢谢,它返回“无法连接到主机”。所以我猜是本地url把事情搞砸了。我在一些WSDL测试站点上测试了它,比如,这些站点也可以从WSDL中获取信息,但它们无法执行任何操作,因为此时它们无法连接。您正在连接的服务应该有一个扩展名
.asmx
,如
TestService.asmx
,而不是当前的
TestService.svc
。我还更新了我的答案。在创建SoapClient对象时,您可以在option数组参数中传递一个“location”条目来准确地执行此操作。您说得对,Sven!谢谢,我看过了,但没想过要试试。
<wsdl:service name="TestService">
<wsdl:port name="BasicHttpBinding_ITestService" binding="tns:BasicHttpBinding_ITestService">
<soap:address location="http://459265-dev1/api/TestService.svc"/>
</wsdl:port>
<wsdl:port name="BasicHttpsBinding_ITestService" binding="tns:BasicHttpsBinding_ITestService">
<soap:address location="https://test.mycustomer.com/api/TestService.svc"/>
</wsdl:port>
</wsdl:service>
array(2) {
  [0]=>
  string(53) "GetMessageResponse GetMessage(GetMessage $parameters)"
  [1]=>
  string(53) "GetMessageResponse GetMessage(GetMessage $parameters)"
}
array(5) {
  [0]=>
  string(21) "struct GetMessage {
}"
  [1]=>
  string(55) "struct GetMessageResponse {
 string GetMessageResult;
}"
  [2]=>
  string(8) "int char"
  [3]=>
  string(17) "duration duration"
  [4]=>
  string(11) "string guid"
}
<?php
    try {
        ini_set('soap.wsdl_cache_enabled',0);
        ini_set('soap.wsdl_cache_ttl',0);

        $url = "https://test.mycustomer.com/api/TestService.asmx?wsdl";
        $client = new SoapClient($url, array("trace" => 1, "exception" => 0));

        $result = $client->GetMessage(NULL);

        echo "<pre>".print_r($result, true)."</pre>";
        if($result->GetMessageResult->Status == "Success")
        {
            echo "Item deleted!";
        }
    }
    catch (SoapFault $exception) {
        echo $exception->getMessage();
    }
?>
class MySoapClient extends SoapClient
{
    public function __doRequest($request, $location, $action, $version, $one_way = 0)
    {
        $response = parent::__doRequest($request, "https://test.mycustomer.com/api/TestService.svc", $action, $version, $one_way);

        return($response);
    }
}