今天是: 收藏本站 设为主页
网站首页 >  技术专栏  >  php  > 

YII如何获取Soap Client的Soap Header信息

日期:2012-05-14  点击率:3067


先要介绍一下soap的相关概念
SOAP 是基于 XML 的简易协议,可使应用程序在 HTTP 之上进行信息交换。
或者更简单地说:SOAP 是用于访问网络服务的协议。

一条 SOAP 消息就是一个普通的 XML 文档,包含下列元素:
1 必需的 Envelope 元素,可把此 XML 文档标识为一条 SOAP 消息
2 可选的 Header 元素,包含头部信息
3 必需的 Body 元素,包含所有的调用和响应信息
4 可选的 Fault 元素,提供有关在处理此消息所发生错误的信息

语法规则
1 SOAP 消息必须用 XML 来编码
2 SOAP 消息必须使用 SOAP Envelope 命名空间
3 SOAP 消息必须使用 SOAP Encoding 命名空间
4 SOAP 消息不能包含 DTD 引用
5 SOAP 消息不能包含 XML 处理指令

基本消息结构:
代码
  1. <?xml version="1.0"?>   
  2. <soap:Envelope   
  3. xmlns:soap="http://www.w3.org/2001/12/soap-envelope"  
  4. soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">   
  5. <soap:Header>   
  6.   ...   
  7. </soap:Header>   
  8. <soap:Body>   
  9.   ...   
  10.   <soap:Fault>   
  11.     ...   
  12.   </soap:Fault>   
  13. </soap:Body>   
  14. </soap:Envelope>  


SOAP HTTP Binding
HTTP + XML = SOAP
SOAP 请求可能是 HTTP POST 或 HTTP GET 请求。
HTTP POST 请求规定至少两个 HTTP 头:Content-Type 和 Content-Length。

代码
  1. POST /item HTTP/1.1   
  2. Content-Type: application/soap+xml; charset=utf-8  


代码
  1. POST /item HTTP/1.1   
  2. Content-Type: application/soap+xml; charset=utf-8   
  3. Content-Length: 250  



在PHP中实现client和server,带soap header
client
代码
  1. $cli = new SoapClient(null,   
  2.          array('uri' =>'http://localhost/namespace/',   
  3.                'location' => 'http://localhost/server.php',   
  4.                'trace' => true));   
  5.                   
  6. //auth为服务端要处理的函数  12345689为参数    
  7. $h = new SoapHeader('http://localhost/namespace/',   
  8.                  'auth''123456789'false, SOAP_ACTOR_NEXT);   
  9. $cli->__setSoapHeaders(array($h));   
  10. try{   
  11.     echo $cli->say();   
  12. }catch (Exception $e){   
  13.     echo $e->getMessage();   
  14. }  


server
代码
  1. class Server{   
  2.    public function auth($a)   
  3.    {   
  4.      if($a != '123456789'){   
  5.        throw new SoapFault('Server''111');   
  6.      }   
  7.    }   
  8.   
  9.    public function say()   
  10.    {   
  11.      return 'Hi';   
  12.    }   
  13. }   
  14.   
  15. $srv = new SoapServer(null,    
  16.         array('uri' =>'http://localhost/namespace'));   
  17. $srv->setClass('Server');   
  18. $srv->handle();  



在YII中由于可以利用框架的功能,所以相对处理简单些。
client
代码
  1. $cli = new SoapClient("localhost/test/quote", array('trace'=>1));   
  2. $h = new SoapHeader('http://localhost/namespace/''auth',    
  3.               array('pwd'=>'123456789''usr'=>'abc'),    
  4.                false, SOAP_ACTOR_NEXT);   
  5. $ttt = $cli->__setSoapHeaders(array($h));   
  6. try {   
  7.     echo $cli->say("2");   
  8. catch (Exception $e) {   
  9.     echo $e->getMessage();   
  10. }  


server
代码
  1. class TestController extends CController   
  2.                                 implements IWebServiceProvider{   
  3.   public $rawPOST;    
  4.   public $SOAP_HEADERS;   
  5.   
  6.   public function actions(){   
  7.     return array(   
  8.       'quote'=>array(   
  9.       'class'=>'CWebServiceAction',   
  10.       )   
  11.     );   
  12.   }   
  13.   
  14.   public function beforeWebMethod($service){   
  15.       //继承IWebServiceProvider的接口,可以在这里处理Soap Header   
  16.     $this->rawPOST = file_get_contents('php://input');   
  17.     $xml = simplexml_load_string($this->rawPOST);   
  18.     $headers = $xml->xpath('//SOAP-ENV:Header');   
  19.     foreach($headers as $header)   
  20.     {   
  21.        $items = $header->xpath('ns2:auth');   
  22.        foreach($items as $value)   
  23.             $this->SOAP_HEADERS[$value->getName()] = (array)$value;   
  24.     }   
  25.     return true;   
  26.   }   
  27.      
  28.   public function auth($a){   
  29.       //在soap client函数里指定处理请求,$a为传过来的参数   
  30.     if($a->item[0]->['value'] != '123456789'){   
  31.       throw new SoapFault('Server',"INVALID REQUEST");   
  32.     }   
  33.   }   
  34.   
  35.   
  36.   public function afterWebMethod($service){   
  37.     return true;   
  38.   }   
  39.      
  40.   /**  
  41.    * Say  
  42.    * @param int $a  
  43.    * @return string  
  44.    * @soap  
  45.   */  
  46.   public function say($t){   
  47.     return "Hello $t";   
  48.   }     
  49. }  


在client端,可以利用__getLastRequest和__getLastResponse来获取请求的xml
  但必须在soapclient构造函数里options参数,加上trace=1
代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <SOAP-ENV:Envelope >   
  3. <SOAP-ENV:Header>   
  4.     <ns2:auth>   
  5.         <item><key>pwd</key><value>123456789</value></item>   
  6.         <item><key>usr</key><value>abc</value></item>   
  7.     </ns2:auth>   
  8. </SOAP-ENV:Header>   
  9. <SOAP-ENV:Body>   
  10.     <ns1:say>   
  11.         <t xsi:type="xsd:int">2</t>   
  12.     </ns1:say>   
  13. </SOAP-ENV:Body>   
  14. </SOAP-ENV:Envelope>   
  15.   
  16. <?xml version="1.0" encoding="UTF-8"?>   
  17. <SOAP-ENV:Envelope >   
  18. <SOAP-ENV:Body>   
  19.     <ns1:sayResponse>   
  20.         <return xsi:type="xsd:string">Hello 2</return>   
  21.     </ns1:sayResponse>   
  22. </SOAP-ENV:Body>   
  23. </SOAP-ENV:Envelope>  






下一篇:使用.htaccess实现301重定向   上一篇:ubuntu系统下更改mysql数据目录的方法