views:

59

answers:

1

I'm trying to use a Web Service using PHP and SOAP. The Web Service is built in .NET and hosted on an ASP server. I'm using the following code to interact with the API but I keep getting an error with parsing WSDL. The PHP UNIX server has an SSL certificate, the web service host also has an SSL certificate and I'm using https to initiate the transaction.

This particular API call requests a string for a membership number:

$wsdl='https://domain.com/ws.asmx?wsdl';

$client=new SOAPClient($wsdl, array('exceptions'=>0));

$result=$client->IsMemberCurrent('123456789');

Error:

Fatal error: SOAP-ERROR: Parsing WSDL: Couldn't load from 'domain/ws.asmx?wsdl' : Start tag expected, '<' not found in index.php on line 4

I can see the WSDL contents but the error message I'm getting via PHP suggests it either can't see or can't process the WSDL file?

SOAP 1.2 service description:POST /SubscriberAPI.asmx HTTP/1.1
Host: subdomain.domain.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"&gt;
  <soap12:Body>
    <IsMemberCurrent xmlns="http://www.domain.com/"&gt;
      <MembershipNo>string</MembershipNo>
    </IsMemberCurrent>
  </soap12:Body>
</soap12:Envelope>
A: 

It seems that you cannot access the WSDL file. So you need to diagnose the issue.

Try

echo htmlentities(file_get_contents($wsdl));

It will give you better insight as to what PHP gets as a response.

Once you have got the SoapClient working your next line of code will not work as expected.

You need wrap your parameter in an associative array otherwise the web service will not recognize it.

Also the response returned by the .NET web service will be a IsMemberCurrentResponse object, which contains a IsMemberCurrentResult, so you need to replace your last line with the following.

$params = array('MembershipNo'=>'1234567890');
$response = $client->IsMemberCurrent($params);
$result = $response->IsMemberCurrentResult;
Chris Diver
Thanks for the tip. I've done as suggested, but the return I get is the same - couldn't load error. Could this mean a Firewall issue since I am able to see the WSDL file when I try to access it directly from the web browser?
baswoni
If it errors on file_get_contents then it is an issue connecting to the IIS box and not an issue with IIS or ASP.NET.It could be a firewall issue - but need some more information. Do you get any more information other than couldn't load?Is the web browser you are using located on the UNIX server? Can you try over http rather than https?
Chris Diver
My web server uses PHP/UNIX and I've tried both HTTP and HTTPS but the error I get is that it can't parse the WSDL file. The error message you see in my original post is all of the information that PHP is showing unless there's any debug methods that can be used to extract more info?
baswoni
The line of code I asked you to try shouldn't have given you a "can't parse the WSDL file" error as it wouldn't have attempted to parse anything. You'd need to execute that line in a new PHP document or comment out the SoapClient lines. If that's what you did then I'd recommend using a browser on the UNIX server to see what is returned, if you get an error you can go from there, otherwise if all is okay then it will be PHP specific.
Chris Diver
I'm not sure what you mean by parameter? Could you clarify this. WSDL has the following defined:<wsdl:message name="IsMemberCurrentSoapIn"><wsdl:part name="parameters" element="tns:IsMemberCurrent"/></wsdl:message><wsdl:message name="IsMemberCurrentSoapOut"><wsdl:part name="parameters" element="tns:IsMemberCurrentResponse"/>
baswoni
Parameters are what to pass to the web service and what the web service responds with, in your case the input parameter is 'MembershipNo'. I've edited the answer, hopefully it is clearer. Did you fix your WSDL issue? there is also the possibility to save your WSDL document to the UNIX server and access it locally.
Chris Diver
Thanks for your help so far Chris. I've not been able to get past the parsing issue with WSDL file, so I've followed your advice and saved a local copy of it to the UNIX server I'm trying to access it from. Now using: $wsdl='http://www.domain.com/api.wsdl';$client=new SOAPClient($wsdl);$params = array('MembershipNo'=>'76543');$response=$client->IsMemberCurrent('76543');$result = $response->IsMemberCurrentResult;echo $result;Error I get:Fatal error: Uncaught SoapFault exception: [HTTP] Could not connect to host...
baswoni
Fatal error: Uncaught SoapFault exception: [HTTP] Could not connect to host in /home/domain/public_html/index.php:7 Stack trace: #0 [internal function]: SoapClient->__doRequest('<?xml version="...', 'https://domain.da...', 'http://www.subs...', 1, 0) #1 [internal function]: SoapClient->__call('IsMemberCurrent', Array) #2 /home/baswcouk/public_html/dev/index.php(7): SoapClient->IsMemberCurrent('76543') #3 {main} thrown in /home/domain/public_html/dev/index.php on line 7
baswoni
From that error message it sounds like the UNIX server cannot resolve the domain name of your ASP.NET web service. Depending on how IIS is set up you should be able to do it by IP address, can you try http://xxx.xxx.xxx.xx/service.asmx?wsdl instead - replacing xxx.xxx.xxx.xxx with the IP address of your IIS server and use http instead of https. Also in your code you need to change $client->IsMemberCurrent('76543'); to $client->IsMemberCurrent($params);
Chris Diver
Made the change to the code and used IP address of the web service host + port number with the address to the WSDL and I now get a 503 Service Unavailable error. Is this a firewall issue even though I can access WSDL from a web browser? Or is it a server issue on my end?
baswoni
A 503 is returned from IIS web server, which means you are getting a response from the server so it isn't a firewall issue. Is the web service on a server that you control? It's possible the web server is purposely configure to only work by hostname (domain name). You could try an 'nslookup domainname' on the UNIX server to see if it can find the IP address, if not then you can manually add it to your /etc/hosts file.
Chris Diver
I don't have control of the web service server but I do have contact with the provider. I just tried doing nslookup and it returned a not found message. How do I go about adding the IP address to my hosts file? I've looked in the etc folder and dont see the file, or can I just create a 'hosts' file and add in IP address *space* domain name?
baswoni
On debian you can do this. It might depend on your distribution, but give it a go and see what happens.
Chris Diver
No luck on that one. It hasn't worked. I'm going to get in touch with the web service provider to see if we can figure out why I can't connect.
baswoni
It will be down to your UNIX servers configuration as you can access the web service from a browser.
Chris Diver
I put the question to my UNIX hosting provider as to whether there are any restrictions or configuration issues that would prevent me from using SOAP. I've got an unused ASP-based hosting account which I'm going to see if I can get the web service provider to use to upload a sample API call using SOAP. This should help me figure out whether its my code that's not working or if its a server configuration issue.
baswoni
Hosting provider has said there shouldn't be any issues. Web Service provider have come back saying it could be because of a mixture of PORT and SSL issue so they've removed the need for a port and SSL encryption to see if we can narrow down the issue. Still no luck though.
baswoni
Although this time, I am getting a 503 Service Unavailable error. Could be a timeout issue so I've checked with the hosting provider to see if that's the case.
baswoni