PHP Soap Server如何知道被调用的方法

时间:2012-05-22 15:36:16

标签: php soap soapserver

在PHP中,我想知道SOAP调用的方法是什么。这是一个要理解的样本......

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

我想知道的是将在handle()

中执行的方法的名称

谢谢!

4 个答案:

答案 0 :(得分:9)

在我看来,在这种情况下访问被叫操作名称的最干净,最优雅的方法是使用某种 Wrapper Surrogate 设计模式。根据您的意图您可以使用DecoratorProxy

作为一个例子,假设我们想要动态地向Handler对象添加一些额外的功能而不触及类本身。这样可以使Handler类更清洁,从而更专注于其直接责任。这样的功能可以是记录方法及其参数或实现某种缓存机制。为此,我们将使用装饰器设计模式。而不是这样做:

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

我们将执行以下操作:

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

如果您想控制对处理程序操作的访问权限,例如,为了强制执行访问权限,请使用代理设计模式。

答案 1 :(得分:1)

我知道这是一个老帖子,但有人可以使用这个解决方案。应该可以从原始HTTP POST数据中提取数据。您不能使用$_POST,因为它是空的,但您可以使用预定义变量$HTTP_RAW_POST_DATA,其中包含XML格式的SOAP请求字符串。

方法名称应位于<soapenv:Body>标记的第一个节点中,如下所示:

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

你可能会用SimpleXML之类的东西来解析它,或者可能会使用一些常规表达式来获取methodName但是请记住字符串urn:是标题中定义的命名空间,因此它可以是任何东西。< / p>

答案 2 :(得分:0)

虽然不是最好的方法,但你可以某种方式使用这个http://danpolant.com/use-the-output-buffer-to-debug-a-soap-server/

对于快速且非常脏的方法(请仅将其用于一次性调试而不是生产代码!):只需在方法体中为每个SOAP方法的名称分配一个全局变量,并执行任何您想要的操作在SoapServer完成其工作后使用它,如上面的链接所述。这样的事情(未经测试的代码):

$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

答案 3 :(得分:0)

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