Link to home
Start Free TrialLog in
Avatar of caliea
caliea

asked on

Trouble receiving WebService SOAP XML response in PHP

From my PHP program, I am successfully able to send a SOAP/HTP request to a remote server. Using wireshark/etheral, I confirmed that the expected response is being obtained from the remote server. Using SoapUI and wireshark/ethereal , I further confirmed that request/response in SoapUI and wireshark are exactly the same.
  However, in my PHP program I am not receiving the SOAP response.

Please review the code snippet and comments and advise.
Thankyou
// Open the Socket
$fp = fsockopen('stage.xxxxxx.com',80,$errno,$errstr,30);
// TEST FOR VERIFICATION
if (!$fp) // HTTP ERROR
{
        die("fsockopen() FAILED \n\n ERRNO=$errno \n\n 
              ERRSTR=$errstr \n\n");
}

// WITH HTTP OPEN - WRITE HEADER AND REQUEST
// Header and Request have been properly created and 
// confirmed via echo command, SoapUI and wireshark
fputs ($fp, $header . $xml);

// HTTP OPEN - READ WEBSERVICE RESPONSE, INCLUDING HEADERS 
// AND BODY
$reply  = '';
while (!feof($fp))
{
        $reply  .= fgets ($fp, 128);
        
}
fclose($fp);
echo $reply;

// Upon executing the above, I get the following error msg:
// Fatal error: Maximum execution time of 60 seconds exceeded 
// and it mentions the fgets line

// Instead of fputs, I also tried fwrite and I get the 
// following output when I attempt to echo the response
HTTP/1.1 200 OK Date: Fri, 20 Aug 2010 02:10:56 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 4.0.30319 Cache-Control: private, max-age=0 Content-Type: application/soap+xml; charset=utf-8 Content-Length: 3543 Fatal error: Maximum execution time of 60 seconds exceeded 

// From the above it seems the the content is there since it is showing a content length of 3543. However I am not being able to see and access the content

Open in new window

Avatar of Richard Quadling
Richard Quadling
Flag of United Kingdom of Great Britain and Northern Ireland image

What is the URL of the WSDL?

I'll use a tool called WSDL2PHP (available from http://sourceforge.net/projects/wsdl2php/ and look at RazorsEdgeUK's patches) to create a set of client classes which do all the hard lifting for you.

You can alter the time limit ...

set_time_limit(n);

where n = 0 === forever or some other value to represent seconds ...

set_time_limit(600); // 10 minutes.

But, getting a WSDL file should be VERY VERY quickly.

What version of PHP are you using? Hopefully V5.2+ (makes things a LOT easier if you are, compared to a V4). Ideally a V5.3+
Avatar of caliea
caliea

ASKER


The URL of the WSDL is:
http://stage.valuetopup.com/posaservice/servicemanager.asmx?WSDL

PHP Version is 5.3.1
Here is the file produced using wsdl2php.

Now you can ...

try
      {
      $sm = new ServiceManager
            (
            $wsdl = "http://stage.valuetopup.com/posaservice/servicemanager.asmx?WSDL",
            $options = array
                  (
                  'encoding'  => 'ISO-8859-1',
                  'exception' => True,
                  'trace'     => True,
                  )
            );
      
      $sm->xxx(yyy,zzz);
      }
catch(Exception $e)
      {
      die($e->getMessage());
      }


where xxx are methods for the service.

No XML, SOAP, or anything complicated.
ServiceManager.php
Avatar of caliea

ASKER

When I run the following test, I get the message:

Fatal error: Maximum execution time of 60 seconds exceeded in C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\soap\ServiceManager.php on line 0

Prior to running this code, in php.ini, I uncommented the following line:
extension=php_soap.dll
and restarted apache
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title></title>
    </head>
    <body>
        <?php
         include_once "ServiceManager.php";

         $sm = new ServiceManager
            (
            $wsdl = "http://stage.valuetopup.com/posaservice/servicemanager.asmx?WSDL",
            $options = array
                  (
                  'encoding'  => 'ISO-8859-1',
                  'exception' => True,
                  'trace'     => True,
                  )
            );
                  
         echo "Init Done";

        ?>
    </body>
</html>

Open in new window

Hmmmm...

Can you take out the $sm call?

So, just include the ServiceManager.php script.

Avatar of caliea

ASKER

I ran the following code and it runs successfully.
End of Test message is displayed in the browser window
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title></title>
    </head>
    <body>
        <?php
         include_once "ServiceManager.php";
                  
         echo "End of Test";

        ?>
    </body>
</html>

Open in new window

In my testing locally, it was all OK.

Can you check the SOAP ini settings : http://docs.php.net/manual/en/soap.configuration.php

Avatar of caliea

ASKER

I disconnected the VPN client and am able to instantiate the ServiceManager Class.

Per Authentication requirement of the Service Provider from their documentation:
The userid and pw are passed to a web service through the web service header. In most cases the proxy generator should generate the "AuthenticationHeader" class from the wsdl specification and the developer should be able to set that header in the code. The XML payload of the authentication header is as follows:
<AuthenticationHeader xmlns="http://www.pininteract.com">
<userId>user123</userId>
<password>pass123</password>
</AuthenticationHeader>

So the SOAP header for each call needs to include the above payload.

In the manual approach that I was taking earlier, I was creating the XML (Envelope+Header+Body) as follows:
$xml = '
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:pin="http://www.pininteract.com">
<soap:Header>
<pin:AuthenticationHeader>
<pin:userId>user123</pin:userId>
<pin:password>pass123</pin:password>
</pin:AuthenticationHeader>
</soap:Header>
<soap:Body>
<pin:GetCarrierList>
<pin:version>1.0</pin:version>
</pin:GetCarrierList>
</soap:Body>
</soap:Envelope>
';

Using SoapUI and Wireshark, I verified that the Request was composed correctly and the expected response was coming back (the problem was that PHP was not processing the response).

Per one of your appends above, with the suggested method, we need to do the following:
$sm->xxx(yyy,zzz);
     
where xxx are methods for the service.

So how can I meet the Service Provider requirement of having the authentication header in the soap Header section for each Service Method Call ?
Thanks

The class ServiceManager is a subclass of SoapClient.

SoapClient has a method called SoapClient::__setSoapHeaders (See : http://docs.php.net/manual/en/soapclient.setsoapheaders.php)

http://docs.php.net/manual/en/soapclient.setsoapheaders.php#93460 has some notes regarding a more complex usage.

I've not used SoapHeaders in my work. If you can give me a few minutes, I'll construct something for you to test.

So, setting the header SHOULD be (see snippet).Once you've set the header, you should be able to make the xxxx calls.Hopefully something along the lines of (see snippet).UNTESTED!!!! May have typos - it is late for me (10 past midnight).Hopefully this will at least help you get some of the way.One thing that is different here is that the request/response are objects in their own right. I've always felt that that method was a bit cumbersome.So, you had to do ...$request = new request;$request->param1 = value1;$request->param2 = value2;$service->method($request);rather than ...$service->method(value1, value2);sort of thing.
<?php
include_once 'ServiceManager.php';

try
	{
	$sm = new ServiceManager
		(
		$wsdl = "http://stage.valuetopup.com/posaservice/servicemanager.asmx?WSDL",
		$options = array
			(
			'encoding'  => 'ISO-8859-1',
			'exception' => True,
			'trace'     => True,
			)
		);
	
	$sm->__setSoapHeaders
		(
		new SOAPHeader
			(
			'http://pininteract.com',
			'AuthenticationHeader',
			array
				(
				'userId'   => 'user123',
				'password' => 'pass123',
				)
			)
		);

	$GCLRequest = new GetCarrierList;
	$GCLRequest->version = '1.0';

	$GCLResponse = $sm->GetCarrierList($GCLRequest);
	
	print_r($GCLResponse->carrierListResponse->carriers);
	}
catch(Exception $e)
	{
	die($e->getMessage());
	}
?>

Open in new window

Avatar of caliea

ASKER

I tried the logic as per your append above and get an XML exception. Wireshark trace file review of the request and response shows an issue/problem with the XML header. Kindly take a look at the attached files:
test.php:  PHP program as per logic provided in you append above
test-original.php:  PHP program with the original logic that I was trying
wireshark-ReqResp.txt: Wireshark trace file showing the Request and Response packets obtained by running the above 2 test programs

In the test-original.php, I am creating the xml manually and the the correct response is coming back, however PHP is not being able to process it.
So using your technique, we need to make the XML request to be exactly the same as what is in the test-orignal.php and the wireshark trace file for the original test scenario.

The 2 PHP files have the valid userid and password, so you can run them in your environment to submit the requests.
Thankyou
test.php
test-original.php
wireshark-ReqResp.txt
http://docs.php.net/manual/en/soapheader.soapheader.php#88527 seems to comment on this specific issue. It seems .NET doesn't like to build from key/value pairings.

I'm not able to look any further on this until Tuesday (evening travelling, wedding tomorrow, recovery and travelling Monday - not my wedding, so you don't need to send a card or anything).


A simple class like ...

class AuthenticationHeader {
 public $userId = '123user';
 public $password = '123pass';
}

and then use ...

$sm->__setSoapHeaders
            (
            new SOAPHeader
                  (
                  'http://pininteract.com',
                  'AuthenticationHeader',
                  new AuthenticationHeader(),
                  false
                  )
            );

Maybe.

Please have a play with this. I may have some more time in a couple of hours ... sorry for dropping it for a few days.


If you don't get anywhere and need some more help, then certainly try the "Request Attention" option.
Avatar of caliea

ASKER

Hi, Per your append above, I placed the following lines in ServiceManager.php:
class AuthenticationHeader {
  public $userid="ites";
  public $password="Vikram123";
}
 
In the php file, I did the following:
$sm->__setSoapHeaders
            (
            new SOAPHeader
                  (
                  'http://pininteract.com',
                  'AuthenticationHeader',
                  new AuthenticationHeader(),
                        false
                        )
            );

I still get and Exception message. In the Header, I see only the password field being passed. Given below is the information from the Wireshark trace:
POST /posaservice/servicemanager.asmx HTTP/1.1

Host: stage.valuetopup.com

Connection: Keep-Alive

User-Agent: PHP-SOAP/5.3.1

Content-Type: text/xml; charset=utf-8

SOAPAction: "http://www.pininteract.com/GetCarrierList"

Content-Length: 530



<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.pininteract.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://pininteract.com"><SOAP-ENV:Header><ns2:AuthenticationHeader xsi:type="ns1:AuthenticationHeader"><ns1:password>Vikram123</ns1:password></ns2:AuthenticationHeader></SOAP-ENV:Header><SOAP-ENV:Body><ns1:GetCarrierList><ns1:version>1.0</ns1:version></ns1:GetCarrierList></SOAP-ENV:Body></SOAP-ENV:Envelope>
HTTP/1.1 500 Internal Server Error

Date: Mon, 23 Aug 2010 04:28:47 GMT

Server: Microsoft-IIS/6.0

X-Powered-By: ASP.NET

X-AspNet-Version: 4.0.30319

Cache-Control: private

Content-Type: text/xml; charset=utf-8

Content-Length: 617



<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object.

   at ServiceManager.GetCarrierList(String version)

   --- End of inner exception stack trace ---</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>

Change $userid to $userId

Case sensitive I think.

Can you supply the working request (via wireshark) so I can see what is different.

The namespaces are not important (as far as I know), but they do need to point to the right place.
Avatar of caliea

ASKER

I changed $userid to $userId, sorry for the mistake. Now I see both the userid and password being passed in the Request. However, the exception is still there.
Given below is the wireshark trace:
POST /posaservice/servicemanager.asmx HTTP/1.1

Host: stage.valuetopup.com

Connection: Keep-Alive

User-Agent: PHP-SOAP/5.3.1

Content-Type: text/xml; charset=utf-8

SOAPAction: "http://www.pininteract.com/GetCarrierList"

Content-Length: 559



<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.pininteract.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://pininteract.com"><SOAP-ENV:Header><ns2:AuthenticationHeader xsi:type="ns1:AuthenticationHeader"><ns1:userId>ites</ns1:userId><ns1:password>Vikram123</ns1:password></ns2:AuthenticationHeader></SOAP-ENV:Header><SOAP-ENV:Body><ns1:GetCarrierList><ns1:version>1.0</ns1:version></ns1:GetCarrierList></SOAP-ENV:Body></SOAP-ENV:Envelope>
HTTP/1.1 500 Internal Server Error

Date: Tue, 24 Aug 2010 15:15:42 GMT

Server: Microsoft-IIS/6.0

X-Powered-By: ASP.NET

X-AspNet-Version: 4.0.30319

Cache-Control: private

Content-Type: text/xml; charset=utf-8

Content-Length: 617



<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object.

   at ServiceManager.GetCarrierList(String version)

   --- End of inner exception stack trace ---</faultstring><detail /></soap:Fault></soap:Body></soap:Envelope>
Avatar of caliea

ASKER

Given below is the wireshark trace of the scenario where I am manually composing the xml header in the PHP code - The expected response is coming back, however PHP is not processing it . One of the differences is that the Content-Type is specified as below:
Content-Type: application/soap+xml;charset=UTF-8;  (In the working case)
whereas it is text/xml in the above append.
Also, perhaps the namespace values could be an issue.


POST /posaservice/servicemanager.asmx HTTP/1.1

Accept-Encoding: gzip,deflate

Content-Type: application/soap+xml;charset=UTF-8;action="http://www.pininteract.com/GetCarrierList"

User-Agent: Jakarta Commons-HttpClient/3.1

Host: stage.valuetopup.com

Content-Length: 378




<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:pin="http://www.pininteract.com">
<soap:Header>
<pin:AuthenticationHeader>
<pin:userId>ites</pin:userId>
<pin:password>Vikram123</pin:password>
</pin:AuthenticationHeader>
</soap:Header>
<soap:Body>
<pin:GetCarrierList>
<pin:version>1.0</pin:version>
</pin:GetCarrierList>
</soap:Body>
</soap:Envelope>
HTTP/1.1 200 OK

Date: Tue, 24 Aug 2010 15:26:29 GMT

Server: Microsoft-IIS/6.0

X-Powered-By: ASP.NET

X-AspNet-Version: 4.0.30319

Cache-Control: private, max-age=0

Content-Type: application/soap+xml; charset=utf-8

Content-Length: 3543



<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetCarrierListResponse xmlns="http://www.pininteract.com"><carrierListResponse version="1.0" responseCode="000" xmlns="urn:pininteract.com"><carriers><carrier carrierId="8" carrierName="ATT" category="Pin" /><carrier carrierId="9" carrierName="Boost" category="Pin" /><carrier carrierId="11" carrierName="TMobile" category="Pin" /><carrier carrierId="12" carrierName="Verizon" category="Pin" /><carrier carrierId="13" carrierName="Airvoice" category="Pin" /><carrier carrierId="14" carrierName="Call Plus" category="Pin" /><carrier carrierId="15" carrierName="Omni" category="Pin" /><carrier carrierId="16" carrierName="Tracfone" category="Pin" /><carrier carrierId="17" carrierName="STI" category="Pin" /><carrier carrierId="19" carrierName="Page Plus" category="Pin" /><carrier carrierId="20" carrierName="Virgin Mobile" category="Pin" /><carrier carrierId="22" carrierName="Locus Platinum" category="Pin" /><carrier carrierId="23" carrierName="Oxygen" category="Pin" /><carrier carrierId="24" carrierName="Omobile" category="Pin" /><carrier carrierId="25" carrierName="Platinum Tel" category="Pin" /><carrier carrierId="26" carrierName="Net 10" category="Pin" /><carrier carrierId="27" carrierName="Tuyo" category="Pin" /><carrier carrierId="30" carrierName="Xtreme" category="Pin" /><carrier carrierId="31" carrierName="Bravo" category="Pin" /><carrier carrierId="35" carrierName="Movida" category="Pin" /><carrier carrierId="37" carrierName="Airtel India" category="Rtr" /><carrier carrierId="38" carrierName="Ufone Pakistan" category="Rtr" /><carrier carrierId="41" carrierName="Page Plus UNW" category="Pin" /><carrier carrierId="42" carrierName="Total Call" category="Pin" /><carrier carrierId="43" carrierName="Ready Mobile" category="Pin" /><carrier carrierId="44" carrierName="TelCel" category="Rtr" /><carrier carrierId="45" carrierName="Verizon Topup" category="Rtr" /><carrier carrierId="46" carrierName="Tigo Honduras" category="Pin" /><carrier carrierId="47" carrierName="Tigo Guatemala" category="Pin" /><carrier carrierId="48" carrierName="Cricket Paygo" category="Pin" /><carrier carrierId="49" carrierName="Express Airvoice" category="Pin" /><carrier carrierId="50" carrierName="Alltel" category="Pin" /><carrier carrierId="51" carrierName="Globe " category="Rtr" /><carrier carrierId="52" carrierName="TC Unlimited" category="Pin" /><carrier carrierId="53" carrierName="Airvoice Unlimited" category="Pin" /><carrier carrierId="54" carrierName="Powerlink Unlimited" category="Pin" /><carrier carrierId="55" carrierName="H20 Unlimited" category="Pin" /><carrier carrierId="56" carrierName="Digicel HAITI" category="Rtr" /><carrier carrierId="57" carrierName="Digicel JAMAICA" category="Rtr" /><carrier carrierId="58" carrierName="Digicel HONDURAS" category="Rtr" /><carrier carrierId="59" carrierName="Digicel GUYANA" category="Rtr" /><carrier carrierId="60" carrierName="Haiti - Voila" category="Rtr" /><carrier carrierId="61" carrierName="Simple Mobile" category="Pin" /><carrier carrierId="62" carrierName="Viva" category="Rtr" /><carrier carrierId="63" carrierName="Claro" category="Rtr" /><carrier carrierId="64" carrierName="Boost RTR" category="Rtr" /><carrier carrierId="65" carrierName="TM RTR" category="Rtr" /></carriers></carrierListResponse></GetCarrierListResponse></soap:Body></soap:Envelope>
http://docs.php.net/manual/en/book.soap.php#93888 gives a note regarding an error around the content type.

So, let's add the content type to the headers ... not sure how to do that with the normal kit as the content-type is text/xml ... hmmm


Probably not an issue. Can you change the SOAPHeader from http://pininteract.com to http://www.pininteract.com. They are the same in the working example.


.....


Ha! Just realised that the class AuthenticationHeader already exists in the wsdl2php output...

No need to redeclare it.

There is an error in the original code I used ...

new SOAPHeader
      (
      'http://www.pininteract.com',

and NOT

new SOAPHeader
      (
      'http://pininteract.com',



I've attached my latest test code to the snippet below.

The output is ...


Request Headers
---------------
POST /posaservice/servicemanager.asmx HTTP/1.1
Host: stage.valuetopup.com
Connection: Keep-Alive
User-Agent: PHP
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://www.pininteract.com/GetCarrierList"
Content-Length: 341


Request
-------
<?xml version="1.0" encoding="UTF-8"?>
1.0

Response Headers
----------------
HTTP/1.1 500 Internal Server Error
Date: Tue, 24 Aug 2010 23:03:10 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Content-Length: 924

Response
--------
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault>soap:ServerSystem.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: username
   at System.Web.Util.SecUtility.CheckParameter(String&amp; param, Boolean checkForNull, Boolean checkIfEmpty, Boolean checkForCommas, Int32 maxSize, String paramName)
   at System.Web.Security.Membership.GetUser(String username, Boolean userIsOnline)
   at Utility.Authenticate(String userId, String password)
   at ServiceManager.GetCarrierList(String version)
   --- End of inner exception stack trace ---</soap:Fault></soap:Body></soap:Envelope>

Exception
---------
System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: username
   at System.Web.Util.SecUtility.CheckParameter(String& param, Boolean checkForNull, Boolean checkIfEmpty, Boolean checkForCommas, Int32 maxSize, String paramName)
   at System.Web.Security.Membership.GetUser(String username, Boolean userIsOnline)
   at Utility.Authenticate(String userId, String password)
   at ServiceManager.GetCarrierList(String version)
   --- End of inner exception stack trace ---








The error is the validation of the username which is called from System.Web.Security.Membership.GetUser which is called from Utility.Authenticate and that is from ServiceManager.GetCarrierList.

Are you sure that the userId you've given me is accurate.



<?php

require_once 'ServiceManager.php';

$AuthenticationHeader = new AuthenticationHeader;
$AuthenticationHeader->userId="ites";
$AuthenticationHeader->password="Vikram123";

try
	{
	$sm = new ServiceManager
		(
		$wsdl = "http://stage.valuetopup.com/posaservice/servicemanager.asmx?WSDL",
		$options = array
			(
			'encoding'  => 'ISO-8859-1',
			'exception' => True,
			'trace'     => True,
			)
		);
	
	$sm->__setSoapHeaders
		(
		new SOAPHeader
			(
			'http://www.pininteract.com',
			'AuthenticationHeader',
			new AuthenticationHeader
			)
		);

	$GCLRequest = new GetCarrierList;
	$GCLRequest->version = '1.0';

	$GCLResponse = $sm->GetCarrierList($GCLRequest);
	
	print_r($GCLResponse->carrierListResponse->carriers);
	}
catch(Exception $e)
	{
	echo 'Request Headers', PHP_EOL, '---------------', PHP_EOL, $sm->__getLastRequestHeaders(), PHP_EOL;
	echo 'Request', PHP_EOL, '-------', PHP_EOL, $sm->__getLastRequest(), PHP_EOL;
	echo 'Response Headers', PHP_EOL, '----------------', PHP_EOL, $sm->__getLastResponseHeaders(), PHP_EOL;
	echo 'Response', PHP_EOL, '--------', PHP_EOL, $sm->__getLastResponse(), PHP_EOL, PHP_EOL;
	echo 'Exception', PHP_EOL, '---------', PHP_EOL, $e->getMessage(), PHP_EOL;
	}

Open in new window

Avatar of caliea

ASKER

1.
In the new SOAPHeader, I changed new(AuthenticationHeader) to $AuthenticationHeader and the userid & pw is getting passed.The correct Request is being generated and the expected response is coming back.
  In the wireshark trace, BEFORE the POST, I also see a GET message being sent. Why is the GET being sent ? Should this be a concern ? When the XML header is created manually (details in earlier appends), this GET is not there.

2.
Please provide pointers on how to process the Response. Given below is partial info from a response:
stdClass Object ( [carrier] => Array ( [0] => Carrier Object ( [carrierId] => 8 [carrierName] => ATT [category] => Pin ) [1] => Carrier Object ( [carrierId] => 9 [carrierName] => Boost [category] => Pin ) [2] => Carrier Object ( [carrierId] => 11 [carrierName] => TMobile [category] => Pin )

The information of interest in the above is: carrierid-8;  carrierName-ATT;   category-Pin

3.
For future WSDL's, I need to be in a position to be able to generate the ServiceManager.php on my own
 I came across the following link:
http://labs.wso2.org/wsf/php/wsdl2phptool.php

When I use the ServiceManager.php generated by the above link, I get a
Class 'WSClient' not found  error message.

Please advise on the best way to be able to generate the ServiceManager.php file.
Thankyou
ASKER CERTIFIED SOLUTION
Avatar of Richard Quadling
Richard Quadling
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of caliea

ASKER

Thankyou for the solution, and I am glad that it will be useful for your work.

1.
 Please clarify the root cause of the issue. My understanding is that wsdl2php creates a local proxy / class, which are used by the client and facilitates the interaction with the Service Provider.
  The earlier approach that I was taking involved creating the XML manually, opening a socket connection to the service provider, do a post and process the response with fgets(). Per the wireshark trace, the request was being properly created and the expected response was coming back. So why does fgets() not process the response ? And why does wsdl2php based solution not have the issue that fgets() has ?

2.
At the command prompt on my WinXP system, I typed the following:
wsdl2php.php http://stage.valuetopup.com/posaservice/servicemanager.asmx?WSDL 
and Microsoft Expression Web, which is installed on the system, starts up and loads the php file.

I then loaded the wsdl2php.php file into Netbeans and could not find the way to specify the WSDL as a parameter.

Please advise.
1 - You were not detecting the end of transmission appropriately. But also, in general, you were doing things the hard way. The very very VERY hard way.

The wsdl2php solution just produces a set of classes which utilises the SoapClient class built into PHP. The wsdl2php script doesn't actually communicate with the service. It just uses a URL parameter to read the WSDL file. From there it is just plain text and xml manipulation.


2 - You will need to have PHP installed and accessible via the command line.

Read the following manual pages

http://docs.php.net/manual/en/install.windows.manual.php
http://docs.php.net/manual/en/install.windows.commandline.php <<<< VERY IMPORTANT ONE!!!

The wsdl2php script is a command line script. You supply the WSDL url to the command line.

wsdl2php URL

Avatar of caliea

ASKER

Yes, the technique taught by you is what I will be using in my current and future work related to Web Services development in the PHP environment.

 For future reference, could you briefly explain why fgets() was not detecting the end of transmission appropriately. For file i/o it seems to work fine.However, per your above append there seems to be issue with fgets() when used with socket i/o.

Thankyou very much for your time and effort and I am ready to close this issue. For future questions on this topic is it possible to specifically specify your userid in order to request your assistance while opening a query/question ?

Not 100% on this.

I wonder if an EOF is being sent or if the socket is being closed by the remote server.

If neither of these happen, then the fgets() will sit there waiting until it can read all the bytes it has been asked to read.

If there is nothing coming down the pipe, then it just sits there.

You could prove this by fgets() 1 character at a time and echoing it.

See what is the last character you receive.

Compare that with what is happening in WireShark with regard to the communication (being closed).
I'm watching the SOAP topic area and I watch the PHP ones too. So if you have a question, I should see it. Others may answer it though. It's all good!

Ray Paseur is a top expert, so what he says would be good too. And we have different opinions on web services - he prefers RESTful interfaces. I prefer SOAP. Both have +ve/-ves. It'll be upto you to decide which you want/need.
Avatar of caliea

ASKER

Thankyou for providing a solution to this issue. Your explanations, support and response time were exceptionally good.
fgets() is a blocking call. If there is no data to read it waits.

fread() is the one to use.

But you won't be doing that now though, will you ... ;-)

Good question. Glad to have helped AND learn at the same time.