简体   繁体   中英

PHP Soap Server How to know called method

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 !!

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.

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

通常(但并非总是如此,取决于客户端)设置了$_SERVER['HTTP_SOAPACTION'] ,您可以从中获取被调用方法的名称。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM