2012-05-22 47 views
2

在PHP中,我想知道SOAP將調用什麼方法。這是理解的......樣品,PHP肥皂服務器如何知道調用方法

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

我想知道的是,將在處理被執行的方法的名稱()

謝謝!!

+0

你爲什麼不看看'http://php.net/manual/en/soapserver.handle。php' – jugnu

+0

@jugnu我已經看到了它,並希望除了手工解析XML來找到答案(然後XML將被解析兩次,以獲得相同的請求),還有另一種方式 – Guile

+0

對於搜索Google進行調試的用戶這個可愛的PHP擴展的解決方案,有人在SoapServer上分享了一篇博文(在SO?的手冊頁上),它提供了一系列調試信息。檢查出來:http://blog.mayflower.de/179-Extending-class-SoapServer-PHP5-for-debugging.html –

回答

9

在我看來,在這種情況下訪問稱爲操作的名字最清潔和最優雅的方式將使用某種包裝代孕設計模式。根據您的意圖您可以使用DecoratorProxy

舉個例子,假設我們要動態地添加一些額外的功能,我們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(); 

如果你想控制訪問處理程序的操作,例如,爲了徵收訪問權限使用代理設計模式。

+0

這正是我所期待的!謝謝! – Guile

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 
+0

謝謝!我正在尋找更生動的解決方案。儘管如此,這是一種快速簡單的方法:-) Thx! – Guile

+0

在這種情況下,我認爲您需要進行更多的挖掘,因爲據我所知,SoapServer不提供此功能。無論如何,關於這門課的許多細節都沒有記錄,3年前,當我使用它時,我最終挖掘了PHP代碼來抓住它們。 –

+0

順便說一下,爲了避免我提供的解決方案中的混亂的全局變量,我想你可以在myClass中使用一個靜態公共成員,每次調用某個方法時都會覆蓋它。之後,你可以像這樣使用它:myClass :: $ myStatic。如果你真的想實現高級調試,那麼也許你應該考慮擴展SoapServer類,這可能是你可以做的最好的事情:http://blog.mayflower.de/archives/179-Extending-class-SoapServer- PHP5-for-debugging.html –

0

通常(但並非總是如此,取決於客戶端)$_SERVER['HTTP_SOAPACTION']設置,你可以從它被調用的方法的名稱。

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:是一個在頭文件中定義的名稱空間,因此它可以是任何東西。