PHPのSOAPクライアント、不正なWSDLからのエラー? 「キャッチされないSoapFault例外:[HTTP]ホストに接続できませんでした」
私はほとんど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"
}
答え :
解決策:
実行したいのは、コードを 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 ....
なので、どのような場合でも例外をキャッチする必要があります。これがお役に立てば幸いです。
答え :
解決策:
部分的に解決しました。問題はwsdlサービス宣言にあり、同じバインディングに対して2つのポートがあります(上記を参照)。 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を機能することがわかっているURLに設定することができました。もう一度実行して、ウェルカムメッセージを受け取りました-yipee!サービスごとに新しいクライアントを拡張する必要があるため、優れたソリューションではありませんが、ハードコードされたURLを取り出し、$ locationのローカルドメインを外部ドメインに置き換えてから、 __doRequestを使用すると、すべてのサービスで機能します。
同様の質問
私たちのウェブサイトで同様の質問で答えを見つけてください。