很久之前做数据对接,对方要求使用SOAP协议,我们作为server提供接口。但当时遇到一个很麻烦的问题,就是对方使用.NET开发,必须要提供WSDL文件才能调用。但是使用ZDE生成的WSDL文件不能被.NET识别,使用NuSoap生成的也失败了。针对这种情况,我们准备对一个.NET生成的WSDL文件进行了改写,所以要求我们的类库越简单通用越好。总体来讲就是只提供一个名为action的接口,我们把所有具体的操作都放到action的参数当中。这样在WSDL文件中描述action的时候就变得非常方便了。
程序共分为3个文件,假设给对方提供的接口地址:http://example.com/interface/server.php 服务类名称:AbcSoapService 函数:action
1、SoapService.class.php:功能内容实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php class AbcSoapServices { // 这里是soap service的入口,任何业务逻辑都通过$command参数传递进来 // $account,$sign 账号和签名是必须。$xml为传入的数据流,对应$command参数 public function action( $account , $sign , $xml , $command ){ } public function getErrorResponse(){ } // 加入业务逻辑处理 private function do_command1(){ } private function do_command2(){ } } |
2、server.php:提供服务的接口
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php require_once ( 'SoapService.class.php' ); $arrOptions = array ( 'uri' => 'namespace' ); //设置命名空间 $wsdl = null; $objSoapServer = new SoapServer( $wsdl , $arrOptions ); $objSoapServer ->setClass( "AbcSoapServices" ); if ( $_SERVER [ "REQUEST_METHOD" ] == "POST" ) { $objSoapServer ->handle(); } else { echo AbcSoapServices::getErrorResponse(); } |
3、soap.wsdl:接口描述。可以与.net兼容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | <? xml version = "1.0" encoding = "utf-8" ?> < wsdl:definitions xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm = "http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc = "http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime = "http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns = "http://example.com/interface/abc/" xmlns:s = "http://www.w3.org/2001/XMLSchema" xmlns:soap12 = "http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http = "http://schemas.xmlsoap.org/wsdl/http/" targetNamespace = "http://example.com/interface/abc/" xmlns:wsdl = "http://schemas.xmlsoap.org/wsdl/" > < wsdl:types > < s:element name = "action" > < s:complexType > < s:sequence > < s:element minOccurs = "0" maxOccurs = "1" name = "account" type = "s:string" /> < s:element minOccurs = "0" maxOccurs = "1" name = "companykey" type = "s:string" /> < s:element minOccurs = "0" maxOccurs = "1" name = "sign" type = "s:string" /> < s:element minOccurs = "0" maxOccurs = "1" name = "command" type = "s:string" /> < s:element minOccurs = "0" maxOccurs = "1" name = "xml" type = "s:string" /> </ s:sequence > </ s:complexType > </ s:element > < s:element name = "actionResponse" > < s:complexType > < s:sequence > < s:element minOccurs = "0" maxOccurs = "1" name = "actionResult" > < s:complexType mixed = "true" > < s:sequence > < s:any /> </ s:sequence > </ s:complexType > </ s:element > </ s:sequence > </ s:complexType > </ s:element > </ s:schema > </ wsdl:types > < wsdl:message name = "actionSoapIn" > < wsdl:part name = "parameters" element = "tns:action" /> </ wsdl:message > < wsdl:message name = "actionSoapOut" > < wsdl:part name = "parameters" element = "tns:actionResponse" /> </ wsdl:message > < wsdl:portType name = "AbcSoapServicesSoap" > < wsdl:operation name = "action" > < wsdl:input message = "tns:actionSoapIn" /> < wsdl:output message = "tns:actionSoapOut" /> </ wsdl:operation > </ wsdl:portType > < wsdl:binding name = "AbcSoapServicesSoap" type = "tns:AbcSoapServicesSoap" > < wsdl:operation name = "action" > < wsdl:input > < soap:body use = "literal" /> </ wsdl:input > < wsdl:output > < soap:body use = "literal" /> </ wsdl:output > </ wsdl:operation > </ wsdl:binding > < wsdl:binding name = "AbcSoapServicesSoap12" type = "tns:AbcSoapServicesSoap" > < wsdl:operation name = "action" > < wsdl:input > < soap12:body use = "literal" /> </ wsdl:input > < wsdl:output > < soap12:body use = "literal" /> </ wsdl:output > </ wsdl:operation > </ wsdl:binding > < wsdl:service name = "AbcSoapServices" > < wsdl:port name = "AbcSoapServicesSoap" binding = "tns:AbcSoapServicesSoap" > </ wsdl:port > < wsdl:port name = "AbcSoapServicesSoap12" binding = "tns:AbcSoapServicesSoap12" > </ wsdl:port > </ wsdl:service > </ wsdl:definitions > |
这种方式有几个优点:
1、简单,扩展方便,只定义有必要的接口
2、提供单一的WSDL,解决和MS平台必须WSDL的问题
3、没有使用NuSOAP等其他扩展,直接使用PHP自带的SOAP扩展,省去函数描述,简化了复杂度
缺点:
1、实在太简单了……
2、业务接口需要单独描述
说到与.net的WSDL兼容问题,有人给出了一种很取巧的方法。就是用.net重新封装其他语言开发的接口,不需要实际的功能,然后生成WSDL文件给其他语言使用,这样就可以解决了
暂无评论