How to consume a stateful Web Service using PHP's SoapClient class?
Noob question.
I am developing a PHP Web site that consumes a stateful Web Service. Basically, the "flow of control" of my Web site is the following one:
- The user is shown a page.
- The user performs an action.
- The Web site's server does a request to the Web Service, using user input as parameters.
- The Web Service's server executes the request, and goes from state A to state B in the process.
- The Web site's server redirects the user to another page, and we go back to step 1.
My problem is that the Web site loses track of the Web Service's state between requests. How do I make the Web Site keep track of the Web Service's state? I am using PHP's standard SoapClient
class.
I have tried serializing the SoapClient
object into a session variable:
# ws_client.php
<?php
function get_client()
{
if (!isset($_SESSION['client']))
$_SESSION['client'] = new SoapClient('http://mydomain/My开发者_如何转开发WS/MyWS.asmx?WSDL', 'r');
return $_SESSION['client'];
}
function some_request($input1, $input2)
{
$client = get_client();
$params = new stdClass();
$params['input1'] = $input1;
$params['input2'] = $input2;
return $client->SomeRequest($params)->SomeRequestResult;
}
function stateful_request($input)
{
$client = get_client();
$params = new stdClass();
$params['input'] = $input;
return $client->StatefulRequest($params)->StatefulRequestResult;
}
?>
# page1.php
<?php
session_start();
$_SESSION['A'] = some_request($_POST['input1'], $_POST['input2']);
session_write_close();
header('Location: page2.php');
?>
# page2.php
<?php
session_start();
echo $_SESSION['A']; // works correctly
echo stateful_request($_SESSION['A']); // fails
session_write_close();
?>
But it doesn't work. What's wrong with my code?
You will need to use http://php.net/manual/en/soapclient.getlastresponseheaders.php to look for the "set-cookie" header retured by the server and then use http://php.net/manual/en/soapclient.setcookie.php to set that cookie when send the subsequent requests. Sorry, can't write sample code as I don't know any PHP.
For consuming the stateful web service, you need to set the session ID of the server session in the SOAP cookie on client side. By default each time SOAP request is sent, the server generates a unique session ID. To prevent that just set the session ID got from first request in SOAP cookie. That cookie will be sent with your all subsequent soap calls. FOr example if you are consuming an ASP.net webservice using SOAP, then after the first WS call, get the response headers like this:
$client = SoapClient("some.wsdl", array('trace' => 1));
$result = $client->SomeFunction();
$headers = $client->__getLastResponseHeaders();
Now $headers
must contain the session ID with a name like 'ASP.NET_SessionId'. Get the ID from the $headers
and create a cookie as follows:
//$client->__setCookie($cookieName, $cookieValue);
$client->__setCookie('ASP.NET_SessionId', $cookieValue);
Now all the SOAP requests from your client will contain this session ID and your state will persist on the server.
You can also directly get the cookie(s) from the soap client by accessing $my_soapclient->_cookies, so you don't have to parse the response header manually.
See here: Reading the Set-Cookie instructions in an HTTP Response header
But there's nothing in the php manual about this.
精彩评论