在Thinkphp中使用Soap

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值