Persistent PHP web service using SOAP

I am trying to implement a public web service in PHP using a SOAP extension. (Yes, I know that web services are supposed to be stateless, and all I really need to store is some form of session ID, so I don't need to authenticate with every service call). The PHP.net API documentation is somewhat lacking on this and not much written on it.

I found one page that discusses it ( http://bytes.com/forum/thread160816.html ) and implemented the code as a test. I created a small .NET application that consumes a web service and calls each function and displays the result. From what I've read, the PHP SOAP extension will persist class variables between calls as long as the functionality is encapsulated into a class using the setClass () function and the setPersistence () function is passed to SOAP_PERSISTENCE_SESSION.

Here is my code:

<?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();

?>

      

The problem I am running into is that $ name is not persisted between calls - I always get the initialized value, not the value I assign to setName (). As I said, I am trying to preserve the session id after database authentication - if anyone has a better way to do this, I am open to suggestions; however I would like to solve the general case anyway. Does anyone have any idea?

+1


source to share


3 answers


I actually solved my problem.

I worked on the assumption that: 1) .NET handles cookies automatically; and 2) my problem was with PHP. Nothing like this. My PHP code was fine, but I needed to add one more element to my .NET code to handle the session cookie.

After instantiating the web service object, I needed to assign an instance of the CookieContainer class to the web service object. My final client side code is below:



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();
        }
    }
}

      

Thank you anyway!

+1


source


Most soap clients start a new connection on every request, so there is no "session".

If your service is SOAP you can send the session ID somewhere inside the SOAP envelope for every response and ask the client to pass the session ID on every subsequent request.



This is much better as your client now has the key and control over the beheaviour.

0


source


To use a stateful web service, you need to set the server session ID in a SOAP cookie on the client side. By default, every time a SOAP request is sent, the server generates a unique session ID. To prevent this, just set the session ID you received from the first request in the SOAP cookie. This cookie will be sent with your subsequent soap calls. For example, if you are using an ASP.net web service using SOAP, then after the first call to WS, get the response headers like this:

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

      

It $headers

should now contain a session ID with a name such as "ASP.NET_SessionId". Get id from $headers

and create cookie like this:

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

      

Now all SOAP requests from your client will contain this session ID and your state will be persisted on the server.

0


source







All Articles