0

I'm mostly new to SOAP, so I made a little test script to connect to my customer's server. They have a GetMessage command in there, that requires no input or authentication and is just intended to test connectivity:

<?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!";
}
?>

If I run this in the command line I get:

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

And from a browser I get:

PHP Notice: 'SoapClient::__doRequest() [soapclient.--dorequest]: php_network_getaddresses: getaddrinfo failed: Name or service not known' 

In their WSDL for this service, the string "459265" appears here:

<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>

So my question is, is that correct? Should the WSDL have a local url like that, that I can't get to from my box?

A little more info, when I do a var_dump on __getFunctions and __getTypes, I get

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"
}
1
  • Sounds like a question to ask whoever maintains that WSDL, but I certainly think you have identified the problem. Commented Jan 17, 2013 at 17:24

2 Answers 2

2

What you want to do is wrap your code in a try{}, catch{} block. For example,

<?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();
    }
?>

As the error says, Fatal error: Uncaught SoapFault exception: [HTTP] Could not connect to host in ...., so you need to catch the exception in any case. Hope this helps.

Sign up to request clarification or add additional context in comments.

2 Comments

I added that, thanks, and it returned "Could not connect to host". So I guess it's that local url 459265-dev1/api/TestService.svc that's messing things up. I tested it on some WSDL test sites, like soapclient.com/soaptest.html, and those could also get info out of the WSDL, but they couldn't do any actions because at that point they can't connect.
The service that you are connecting to, should have an extension of .asmx, as in TestService.asmx and not TestService.svc as you currently have. I've also updated my answer.
0

Solved it, partially. The problem is in the wsdl service declaration, where it has two ports for the same binding (see above). In php's SoapClient, $location for __doRequest comes from the first binding (forgive me if I'm using the wrong terminology), and the url for that is a local url which is inaccessible to me. So I did this:

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);
    }
}

Extending SoapClient and overriding __doRequest, I was able to set $location to the url I knew would work. Ran it again and got the welcome message - yipee! Not a great solution, since I would have to extend a new client for each service, but to fix that all I have to do is take out the hard coded url, replace the local domain in $location with the external domain, and then call __doRequest with that, and it will work with all the services.

2 Comments

You can pass a "location" entry in the option array parameter when creating the SoapClient object to exactly do this thing.
You're right, Sven! Thanks, I had seen that but didn't think to try it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.