Chad 2010-10-04

Symfony可以引用外部的类库, 1.4当然也不例外。说到类库,不能不提Zend Framework的Zend lib[1]。Zend lib类库包含了很多通用类,功能包括发邮件、数据库访问、权限控制、缓存控制、搜索等等。值得一提的是Zend_Amf[2]支持和Flash/Flex直接以AMF(Action Message Format)交换数据,由于AMF不像SOAP那样用XML来装载数据,所以在传输上有一定优势。但SOAP更为广泛被各种编程语言用来跟其它语言交换数据。

在这里讲讲在Symfony 1.4下使用Zend_Soap搭建Soap Server。

首先要做的是配置Zend的autoloader。在将Zend Lib复制到Symfony的lib/vendor/目录下后,修改ProjectConfiguration.class.php配置文件:

Code - PHPPlain Text
 
  1. // config/ProjectConfiguration.class.php  
  2.   
  3. class ProjectConfiguration extends sfProjectConfiguration {  
  4.   
  5.     protected static $zendLoaded = false;  
  6.   
  7.     public function setup() {  
  8.         $this->enablePlugins('sfDoctrinePlugin');  
  9.         $this->enablePlugins('sfDoctrineGuardPlugin');  
  10.   
  11.         self::registerZend();  
  12.     }  
  13.   
  14.     public static function registerZend() {  
  15.         if (self::$zendLoaded) {  
  16.             return;  
  17.         }  
  18.   
  19.         set_include_path(  
  20.                 sfConfig::get('sf_lib_dir') . '/vendor' . PATH_SEPARATOR . get_include_path()  
  21.         );  
  22.         require_once sfConfig::get('sf_lib_dir') . '/vendor/Zend/loader/Autoloader.php';  
  23.         Zend_Loader_Autoloader::getInstance();  
  24.         self::$zendLoaded = true;  
  25.     }  
  26.   
  27. }  

 

然后,创建自己的Soap Function类:

Code - PHPPlain Text
 
  1. class TestService {  
  2.   
  3.     /** 
  4.      * 
  5.      * @param string $name 
  6.      * @return string 
  7.      */  
  8.     public function sayHelloTo($name){  
  9.         return "Hello! {$name}";  
  10.     }  
  11. }  

这里注意一定要给方法加上php docblocks,标明方法的参数和返回值的类型,以让下面提到的Zend_Soap_AutoDiscover类自动生成WSDL。

 

接着,就可以创建一个方法专门用来生成WSDL(Web Services Description Language)。要做这个功能,Zend Framework的Soap AutoDiscover就显得很好用:

Code - PHPPlain Text
 
  1. class serviceActions extends sfActions {  
  2.   
  3.     public function executeWsdl(sfWebRequest $request) {  
  4.         try {  
  5.             $wsdl = new Zend_Soap_AutoDiscover();  
  6.             $wsdl->setClass('TestService');  
  7.             $wsdl->handle();  
  8.         } catch (Exception $e) {  
  9.             $this->logMessage($e->getMessage());  
  10.         }  
  11.         return sfView::NONE;  
  12.     }  
  13.   
  14. // ...  

 

再下来就是提供让外部访问的API了:

Code - routing.ymlPlain Text
 
  1. soap_test:  
  2.   url: /service/test  
  3.   param: { module: service, action: index }  
Code - PHPPlain Text
 
  1. class serviceActions extends sfActions {  
  2.   
  3. // ...  
  4.   
  5.     public function executeIndex(sfWebRequest $request) {  
  6.         $this->forwardIf(null !== $request->getParameter('wsdl'), 'service''wsdl');  
  7.   
  8.         try {  
  9.             $wsdl = $this->generateUrl('soap_test'array(), true).'?wsdl';  
  10.             $server = new Zend_Soap_Server($wsdl);  
  11.             $server->setClass('TestService');  
  12.             $server->setReturnResponse(true);  
  13.             $this->renderText($server->handle());  
  14.         } catch (Exception $e) {  
  15.             $this->logMessage($e->getMessage());  
  16.         }  
  17.         return sfView::NONE;  
  18.     }  
  19.   
  20. // ...  

 

就这样,Symfony下的Soap Server就搭建完成了,不用reinvent the wheel就是爽。。。

 

最后,写个方法来测试一下:

Code - PHPPlain Text
 
  1. public function executeTestClient(sfWebRequest $request){  
  2.     try{  
  3.         $client = new Zend_Soap_Client('http://inluck.local/service/test?wsdl');  
  4.         $result = $client->sayHelloTo($request->getParameter('name','Chad'));  
  5.     } catch (Exception $e) {  
  6.         $this->logMessage($e->getMessage());  
  7.     }  
  8.     echo $result;  
  9.     return sfView::NONE;  
  10. }  

 

运行成功,大功告成!

 

 

Reference:

1. http://framework.zend.com/

2. http://framework.zend.com/manual/en/zend.amf.html

3. http://www.slideshare.net/hhamon/exposer-des-services-web-soap-et-rest-avec-symfony-14-et-zend-framework