如何使用PHP的SoapClient类来使用有状态的Web服务?

时间:2011-01-11 21:59:36

标签: php web-services session soap-client

Noob问题。

我正在开发一个使用有状态Web服务的PHP Web站点。基本上,我的网站的“控制流程”如下:

  1. 向用户显示一个页面。
  2. 用户执行操作。
  3. 网站的服务器使用用户输入作为参数向Web服务发出请求。
  4. Web服务的服务器执行请求,并在此过程中从状态A进入状态B.
  5. 网站的服务器将用户重定向到另一个页面,我们将返回步骤1.
  6. 我的问题是网站在请求之间失去了对Web服务状态的跟踪。如何使网站跟踪Web服务的状态?我正在使用PHP的标准SoapClient类。

    我尝试将SoapClient对象序列化为会话变量:

    # ws_client.php
    <?php
    function get_client()
    {
        if (!isset($_SESSION['client']))
            $_SESSION['client'] = new SoapClient('http://mydomain/MyWS/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();
    ?>
    

    但它不起作用。我的代码出了什么问题?

3 个答案:

答案 0 :(得分:2)

您需要使用 http://php.net/manual/en/soapclient.getlastresponseheaders.php 查找由服务器退回然后使用的“set-cookie”标题 http://php.net/manual/en/soapclient.setcookie.php 在发送后续请求时设置该cookie。 抱歉,无法编写示例代码,因为我不知道任何PHP。

答案 1 :(得分:0)

要使用有状态Web服务,您需要在客户端的SOAP cookie中设置服务器会话的会话ID。默认情况下,每次发送SOAP请求时,服务器都会生成唯一的会话ID。为了防止这种情况,只需在SOAP cookie中设置第一个请求获得的会话ID。该cookie将与您随后的所有肥皂调用一起发送。 举个例子,如果你使用SOAP消费ASP.net webservice,那么在第一次WS调用之后,得到这样的响应头:

$client = SoapClient("some.wsdl", array('trace' => 1));
$result = $client->SomeFunction();
$headers = $client->__getLastResponseHeaders();

现在$headers必须包含名称为'ASP.NET_SessionId'的会话ID。从$headers获取ID并创建一个cookie,如下所示:

//$client->__setCookie($cookieName, $cookieValue);
$client->__setCookie('ASP.NET_SessionId', $cookieValue);

现在,来自客户端的所有SOAP请求都将包含此会话ID,您的状态将保留在服务器上。

答案 2 :(得分:0)

您还可以通过访问$ my_soapclient-&gt; _cookies直接从soap客户端获取cookie,这样您就不必手动解析响应头。

见这里:Reading the Set-Cookie instructions in an HTTP Response header

但是php手册中没有任何内容可以解决这个问题。