Question

In PHP I would like to know what will be the method called by SOAP. Here is a sample to understand...

$soapserver = new SoapServer();
$soapserver->setClass('myClass');
$soapserver->handle();

What I would like to know is the name of the method that will be executed in handle()

Thank you !!

Was it helpful?

Solution

In my opinion, the cleanest and most elegant way to access the called operation's name in this situation would be using some kind of Wrapper or Surrogate design pattern. Depending on Your intent You would use either the Decorator or the Proxy.

As an example, let's say We want to dynamically add some additional functionality to our Handler object without touching the class itself. This allows for keeping the Handler class cleaner and, thus, more focused on its direct responsibility. Such functionality could be logging of methods and their parameters or implementing some kind of caching mechanism. For this We will use the Decorator design pattern. Instead of doing this:

class MyHandlerClass
{
    public function operation1($params)
    {
        // does some stuff here
    }

    public function operation2($params)
    {
        // does some other stuff here
    }
}

$soapserver = new SoapServer(null, array('uri' => "http://test-uri/"));
$soapserver->setClass('MyHandlerClass');
$soapserver->handle();

We'll do the following:

class MyHandlerClassDecorator
{
    private $decorated = null;

    public function __construct(MyHandlerClass $decorated)
    {
        $this->decorated = $decorated;
    }

    public function __call($method, $params)
    {
        // do something with the $method and $params

        // then call the real $method
        if (method_exists($this->decorated, $method)) {
            return call_user_func_array(
                array($this->decorated, $method), $params);
        } else {
            throw new BadMethodCallException();
        }
    }
}

$soapserver = new SoapServer(null, array('uri' => "http://test-uri/"));
$soapserver->setObject(new MyHandlerClassDecorator(new MyHandlerClass()));
$soapserver->handle();

If You want to control the access to the Handler's operations, for instance, in order to impose access rights use the Proxy design pattern.

OTHER TIPS

I know this is an old post, but someone could make use of this solution. It should be possible to extract data from raw HTTP POST data. You cannot use $_POST, because it's empty but you can use predefined variable $HTTP_RAW_POST_DATA which contains string with SOAP request in XML format.

The method name should be in first node of <soapenv:Body> tag like this:

<!--
    ...
    XML header, SOAP header etc.
    ...
-->
<soapenv:Body>
   <urn:methodName soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <param1 xsi:type="xsd:string" xs:type="type:string" xmlns:xs="http://www.w3.org/2000/XMLSchema-instance">param1 value</param1>
      <param2 xsi:type="xsd:string" xs:type="type:string" xmlns:xs="http://www.w3.org/2000/XMLSchema-instance">param2 value</param2>
   </urn:methodName>
</soapenv:Body>
<!--
    ...
-->

You could probably parse it with something like SimpleXML or maybe use some regular expresion to get methodName but remember that the string urn: is a namespace defined in the header and therefore it could be anything.

Although not the nicest way, you can use this http://danpolant.com/use-the-output-buffer-to-debug-a-soap-server/ somehow.

For the quick and very dirty approach (please use this only for a one-time debug and not in production code!): just assign a global variable with the name of each SOAP method in the method bodies and do whatever you want with it after the SoapServer does its job, as described in the above link. Something like this (untested code):

$method = "";
class test
{
    function call1()
    {
        global $method; $method = "call1";
    }
}
ob_start();
$soapserver = new SoapServer();
$soapserver->setClass('test');
$soapserver->handle();

$mystring = ob_get_contents(); // retrieve all output thus far
ob_end_clean ();               // stop buffering
log($mystring);                // log output
log($method);                  // log method
echo $mystring;                // now send it

Usually (but not always, depends on the client) $_SERVER['HTTP_SOAPACTION'] is set and you can get the name of the called method from it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top