質問

SOAP拡張機能を使用して、PHPでステートフルWebサービスを実装しようとしています。 (はい、Webサービスはステートレスであることになっていることを知っています。私が本当に気にするのは何らかの形のセッションIDだけなので、サービスを呼び出すたびに認証する必要はありません)。 PHP.netのAPIドキュメントにはこれが多少欠けており、他にあまり書かれていません。

それについて説明しているページが1つ見つかりました( http://bytes.com/forum/thread160816.html )およびテストとしてコードを実装しました。 Webサービスを消費し、各関数を呼び出して結果を表示する小さな.NETアプリケーションを作成しました。私が読んだことから、機能がsetClass()関数を使用してクラスにカプセル化され、setPersistence()関数にSOAP_PERSISTENCE_SESSIONが渡される限り、PHP SOAP拡張機能は呼び出し間でクラス変数を保持します。

ここに私のコードがあります:

<?php

class User 
{
    var $name = "Initial value";

    function setName($name) 
    {
        $this->name = $name;

        // Tried this too.
        // $this->name = "Set to string constant" ;
    }

    function getName() 
    {
        // This always returns "Initial value"
        return $this->name;
    }
}


// Tried placing session_start() in several places
// before $server->handle()...
// One guy says this doesn't need to be called.
// I assume it depends on if session autostart is on.
session_start();

$server = new SoapServer(null, array('uri' => 'http://localhost/'));
$server->setClass('User');
$server->setPersistence(SOAP_PERSISTENCE_SESSION);
$server->handle();

?>

私が遭遇する問題は、$ nameが呼び出し間で保持されないことです-setName()に割り当てる値ではなく、常に初期化された値を取得します。私が述べたように、データベースに対して認証した後、セッションIDを永続化しようとしています-これを行うためのより良い方法があれば、私は提案を受け入れます。しかし、私はまだ一般的なケースを解決したいと思います。誰にもアイデアはありますか?

役に立ちましたか?

解決

実際に自分の問題を解決しました。

次の前提の下で作業していました。1).NETはCookieを自動的に処理します。 2)私の問題はPHPにありました。どちらも当てはまりませんでした。 PHPコードは問題ありませんでしたが、セッションCookieを処理するために.NETコードにもう1つの要素を追加する必要がありました。

Webサービスオブジェクトをインスタンス化した後、CookieContainerクラスのインスタンスをWebサービスオブジェクトに割り当てる必要がありました。私の最終的なクライアント側コードは以下のとおりです。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WsTest
{
    public partial class PhpWsForm : Form
    {
        private localhost.MyWebService ws;

        public PhpWsForm()
        {
            InitializeComponent();
            ws = new WsTest.localhost.MyWebService();

            // The line below is the part that I forgot!
            ws.CookieContainer = new System.Net.CookieContainer();
        }

        private void butSetVal_Click(object sender, EventArgs e)
        {
            ws.setName(txtSetVal.Text);
        }

        private void butGetVal_Click(object sender, EventArgs e)
        {
            txtGetVal.Text = ws.getName();
        }
    }
}

とにかくありがとう!

他のヒント

ほとんどの石鹸クライアントは、リクエストごとに新しい接続を開始するため、「セッション」はありません。

SOAPサービスの場合、応答ごとにSOAPエンベロープ内のどこかにセッションIDを送信し、後続のすべての要求でセッションIDを渡すようにクライアントに要求できます。

これは、クライアントが振る舞いを手がかりに制御できるようになったため、はるかに優れています。

ステートフルWebサービスを使用するには、クライアント側のSOAP CookieでサーバーセッションのセッションIDを設定する必要があります。デフォルトでは、SOAP要求が送信されるたびに、サーバーは一意のセッションIDを生成します。これを防ぐには、SOAP Cookieの最初のリクエストから取得したセッションIDを設定するだけです。そのCookieは、その後のすべての石鹸呼び出しで送信されます。 たとえば、SOAPを使用してASP.net Webサービスを使用している場合、最初のWS呼び出しの後に、次のような応答ヘッダーを取得します。

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

Now $ headers には、「ASP.NET_SessionId」などの名前のセッションIDが含まれている必要があります。 $ headers からIDを取得し、次のようにCookieを作成します。

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

クライアントからのすべてのSOAPリクエストにこのセッションIDが含まれるようになり、サーバー上で状態が保持されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top