我是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!";
}
?>
如果我在命令行中运行它,我会得到:
Fatal error: Uncaught SoapFault exception: [HTTP] Could not connect to host in /var/www/my.stage.com/htdocs/common/soaptest.php:8
Stack trace:
#0 [internal function]: SoapClient->__doRequest('<?xml version="...', 'http://459265-d...', 'http://tempuri....', 1, 0)
#1 [internal function]: SoapClient->__call('GetMessage', Array)
#2 /var/www/my.stage.com/htdocs/common/soaptest.php(8): SoapClient->GetMessage(NULL)
#3 {main}
thrown in /var/www/my.stage.com/htdocs/common/soaptest.php on line 8
从浏览器我得到:
PHP Notice: 'SoapClient::__doRequest() [soapclient.--dorequest]: php_network_getaddresses: getaddrinfo failed: Name or service not known'
在这个服务的WSDL中,字符串“459265”出现在这里:
<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>
所以我的问题是,这是正确的吗? WSDL是否应该有这样的本地URL,我无法从我的盒子中找到它?
更多信息,当我在__getFunctions和__getTypes上执行var_dump时,我得到了
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"
}
答案 0 :(得分:2)
您要做的是将代码包装在try{}, catch{}
块中。例如,
<?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();
}
?>
正如错误所示Fatal error: Uncaught SoapFault exception: [HTTP] Could not connect to host in ....
,所以你需要在任何情况下捕获异常。希望这会有所帮助。
答案 1 :(得分:0)
部分地解决了它。问题出在wsdl服务声明中,它有两个端口用于相同的绑定(见上文)。在php的SoapClient中,__ doRequest的$ location来自第一个绑定(如果我使用了错误的术语,请原谅我),而url就是我无法访问的本地URL。所以我这样做了:
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);
}
}
扩展SoapClient并覆盖__doRequest,我能够将$ location设置为我知道可以工作的网址。再次跑了,收到了欢迎辞 - yipee!不是一个很好的解决方案,因为我必须为每个服务扩展一个新的客户端,但要修复我所要做的就是取出硬编码的URL,用外部域替换$ location中的本地域,然后调用__doRequest,它将与所有服务一起使用。