在Thinkphp中使用Soap

来源:互联网 发布:淘宝商城童装女童冬装 编辑:程序博客网 时间:2024/05/29 11:12

1,soap要用到的代码:

<?php //Soap接口服务端 class Server extends Think{     private static $soap;          public static function Init(){//URL采用普通模式         $host = $_SERVER['HTTP_HOST'];         $module = MODULE_NAME;         $action = ACTION_NAME;         if((bool)$_GET['ws']){             self::$soap = new SoapServer("http://".$host."/index.php?m=".$module."&a=".$action);             self::$soap->setClass($module."Action");             self::$soap->handle();         }else{             $wsdl = new Wsdl();             $wsdl->generateWsdl($module."Action","http://".$host."/index.php?m=".$module."&a=".$action."&ws=1");             unset($wsdl);         }     }          public static function UnInit(){         self::$soap = NULL;      } } class Wsdl {      private $_operations;     private $_types;     private $_messages;     private $_namespace;     private $_serviceName;      public function generateWsdl($className, $serviceUrl, $encoding='UTF-8')     {         $this->_operations=array();         $this->_types=array();         $this->_messages=array();         $this->_serviceName=$className;         $this->_namespace="urn:{$className}wsdl";          $reflection=new ReflectionClass($className);         foreach($reflection->getMethods() as $method)         {             if($method->isPublic()){                 $this->processMethod($method);             }         }         header("content-type: text/xml");         echo $this->buildDOM($serviceUrl,$encoding)->saveXML();     }      private function processMethod($method)     {         $comment = $method->getDocComment();         if(strpos($comment,'@soap')===false)             return;                  $methodName = $method->getName();         $comment = preg_replace('/^\s*\**(\s*?$|\s*)/m','',$comment);         $params = $method->getParameters();         $message = array();         $n = preg_match_all('/^@param\s+([\w\.]+(\[\s*\])?)\s*?(.*)$/im',$comment,$matches);         if($n>count($params))             $n = count($params);         for($i=0;$i<$n;++$i)             $message[$params[$i]->getName()] = array($this->processType($matches[1][$i]), trim($matches[3][$i])); // name => type, doc          $this->_messages[$methodName.'Request'] = $message;          if(preg_match('/^@return\s+([\w\.]+(\[\s*\])?)\s*?(.*)$/im',$comment,$matches))             $return = array($this->processType($matches[1]),trim($matches[2])); // type, doc         else             $return = null;                      $this->_messages[$methodName.'Response'] = array('return'=>$return);          if(preg_match('/^\/\*+\s*([^@]*?)\n@/s',$comment,$matches))             $doc = trim($matches[1]);         else             $doc='';         $this->_operations[$methodName]=$doc;     }      private function processType($type)     {         static $typeMap=array(             'string'=>'xsd:string',             'str'=>'xsd:string',             'int'=>'xsd:int',             'integer'=>'xsd:integer',             'float'=>'xsd:float',             'double'=>'xsd:float',             'bool'=>'xsd:boolean',             'boolean'=>'xsd:boolean',             'date'=>'xsd:date',             'time'=>'xsd:time',             'datetime'=>'xsd:dateTime',             'array'=>'soap-enc:Array',             'object'=>'xsd:struct',             'mixed'=>'xsd:anyType',         );         if(isset($typeMap[$type]))             return $typeMap[$type];         else if(isset($this->_types[$type]))             return is_array($this->_types[$type]) ? 'tns:'.$type : $this->_types[$type];         else if(($pos=strpos($type,'[]'))!==false) // if it is an array         {             $type=substr($type,0,$pos);             if(isset($typeMap[$type]))                 $this->_types[$type.'[]']='xsd:'.$type.'Array';             else             {                 $this->_types[$type.'[]']='tns:'.$type.'Array';                 $this->processType($type);             }             return $this->_types[$type.'[]'];         }         else // class type         {             $type=Yii::import($type,true);             $this->_types[$type]=array();             $class=new ReflectionClass($type);             foreach($class->getProperties() as $property)             {                 $comment=$property->getDocComment();                 if($property->isPublic() && strpos($comment,'@soap')!==false)                 {                     if(preg_match('/@var\s+([\w\.]+(\[\s*\])?)\s*?(.*)$/mi',$comment,$matches))                         $this->_types[$type][$property->getName()]=array($this->processType($matches[1]),trim($matches[3]));  // name => type, doc                 }             }             return 'tns:'.$type;         }     }      private function buildDOM($serviceUrl,$encoding)     {         $xml="<?xml version=\"1.0\" encoding=\"$encoding\"?>               <definitions name=\"{$this->_serviceName}\" targetNamespace=\"{$this->_namespace}\"                         xmlns=\"http://schemas.xmlsoap.org/wsdl/\"                         xmlns:tns=\"{$this->_namespace}\"                         xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\"                         xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"                         xmlns:wsdl=\"http://schemas.xmlsoap.org/wsdl/\"                         xmlns:soap-enc=\"http://schemas.xmlsoap.org/soap/encoding/\">                </definitions>";          $dom=new DOMDocument();         $dom->loadXml($xml);         $this->addTypes($dom);         $this->addMessages($dom);         $this->addPortTypes($dom);         $this->addBindings($dom);         $this->addService($dom,$serviceUrl);          return $dom;     }      private function addTypes($dom)     {         if($this->_types===array())             return;         $types=$dom->createElement('wsdl:types');         $schema=$dom->createElement('xsd:schema');         $schema->setAttribute('targetNamespace',$this->_namespace);         foreach($this->_types as $phpType=>$xmlType)         {             if(is_string($xmlType) && strrpos($xmlType,'Array')!==strlen($xmlType)-5)                 continue;  // simple type             $complexType=$dom->createElement('xsd:complexType');             if(is_string($xmlType))             {                 if(($pos=strpos($xmlType,'tns:'))!==false)                     $complexType->setAttribute('name',substr($xmlType,4));                 else                     $complexType->setAttribute('name',$xmlType);                     $complexContent=$dom->createElement('xsd:complexContent');                     $restriction=$dom->createElement('xsd:restriction');                     $restriction->setAttribute('base','soap-enc:Array');                     $attribute=$dom->createElement('xsd:attribute');                     $attribute->setAttribute('ref','soap-enc:arrayType');                     $attribute->setAttribute('wsdl:arrayType',substr($xmlType,0,strlen($xmlType)-5).'[]');                     $restriction->appendChild($attribute);                     $complexContent->appendChild($restriction);                     $complexType->appendChild($complexContent);             }             else if(is_array($xmlType))             {                 $complexType->setAttribute('name',$phpType);                 $all=$dom->createElement('xsd:all');                 foreach($xmlType as $name=>$type)                 {                     $element=$dom->createElement('xsd:element');                     $element->setAttribute('name',$name);                     $element->setAttribute('type',$type[0]);                     $all->appendChild($element);                 }                 $complexType->appendChild($all);             }             $schema->appendChild($complexType);             $types->appendChild($schema);         }          $dom->documentElement->appendChild($types);     }      private function addMessages($dom)     {         foreach($this->_messages as $name=>$message)         {             $element=$dom->createElement('wsdl:message');             $element->setAttribute('name',$name);             foreach($this->_messages[$name] as $partName=>$part)             {                 if(is_array($part))                 {                     $partElement=$dom->createElement('wsdl:part');                     $partElement->setAttribute('name',$partName);                     $partElement->setAttribute('type',$part[0]);                     $element->appendChild($partElement);                 }             }             $dom->documentElement->appendChild($element);         }     }      private function addPortTypes($dom)     {         $portType=$dom->createElement('wsdl:portType');         $portType->setAttribute('name',$this->_serviceName.'PortType');         $dom->documentElement->appendChild($portType);         foreach($this->_operations as $name=>$doc)             $portType->appendChild($this->createPortElement($dom,$name,$doc));     }      private function createPortElement($dom,$name,$doc)     {         $operation=$dom->createElement('wsdl:operation');         $operation->setAttribute('name',$name);          $input = $dom->createElement('wsdl:input');         $input->setAttribute('message', 'tns:'.$name.'Request');         $output = $dom->createElement('wsdl:output');         $output->setAttribute('message', 'tns:'.$name.'Response');          $operation->appendChild($dom->createElement('wsdl:documentation',$doc));         $operation->appendChild($input);         $operation->appendChild($output);          return $operation;     }      private function addBindings($dom)     {         $binding=$dom->createElement('wsdl:binding');         $binding->setAttribute('name',$this->_serviceName.'Binding');         $binding->setAttribute('type','tns:'.$this->_serviceName.'PortType');          $soapBinding=$dom->createElement('soap:binding');         $soapBinding->setAttribute('style','rpc');         $soapBinding->setAttribute('transport','http://schemas.xmlsoap.org/soap/http');         $binding->appendChild($soapBinding);          $dom->documentElement->appendChild($binding);          foreach($this->_operations as $name=>$doc)             $binding->appendChild($this->createOperationElement($dom,$name));     }      private function createOperationElement($dom,$name)     {         $operation=$dom->createElement('wsdl:operation');         $operation->setAttribute('name', $name);         $soapOperation = $dom->createElement('soap:operation');         $soapOperation->setAttribute('soapAction', $this->_namespace.'#'.$name);         $soapOperation->setAttribute('style','rpc');          $input = $dom->createElement('wsdl:input');         $output = $dom->createElement('wsdl:output');          $soapBody = $dom->createElement('soap:body');         $soapBody->setAttribute('use', 'encoded');         $soapBody->setAttribute('namespace', $this->_namespace);         $soapBody->setAttribute('encodingStyle', 'http://schemas.xmlsoap.org/soap/encoding/');         $input->appendChild($soapBody);         $output->appendChild(clone $soapBody);          $operation->appendChild($soapOperation);         $operation->appendChild($input);         $operation->appendChild($output);          return $operation;     }      private function addService($dom,$serviceUrl)     {         $service=$dom->createElement('wsdl:service');         $service->setAttribute('name', $this->_serviceName.'Service');          $port=$dom->createElement('wsdl:port');         $port->setAttribute('name', $this->_serviceName.'Port');         $port->setAttribute('binding', 'tns:'.$this->_serviceName.'Binding');          $soapAddress=$dom->createElement('soap:address');         $soapAddress->setAttribute('location',$serviceUrl);         $port->appendChild($soapAddress);         $service->appendChild($port);         $dom->documentElement->appendChild($service);     } } ?> 

2,服务端调用方式:

 public function ExamSoap(){         import('@.ORG.Soap');         Server::Init();     }          /**     *   @param array     *   @return string     *   @soap     */     public function SendExamScore($arr){         return $arr[0]."  ".$arr[1];     } 

在这里主要是ExamSoap调用。而SendExamScore函数主要是提供的接口。

$soap = new SoapClient("http://*.com/index.php?m=Public&a=ExamSoap"); $soap->SendExamScore(array($user["user_workno"],($score + $k_score),$user["fid"])); unset($soap); 



0 0
原创粉丝点击