一个.NET调用PHP Web Service的典型例子
最近一个项目由WinForm直接访问DB2移植到WinForm通过PHP Web Service来访问DB2”。
这个命题的难点不是访问DB2,而是.NET调用PHP Web Service。对于我这个长期作.NET,之前一直以为只有通过.NET调用PHP Web Service……的人来说,真是有点强“聪”所难了。
但是问题还是要解决的,期限就摆在眼前呢。经过一番调查,终于有了眉目,现在分享给大家。
首先要说明的,PHP服务器需要至少需要两个文件——一个WSDL文件和一个PHP文件。WSDL文件是一种机读的XML文件,用于描述WebService提供的服务和调用方法(对于.NET则可以自动生成调用代码,十分好用),php文件就是真正实现的WEB服务了。
1)PHP服务器端代码
1-1)TestWebService.php代码
- TestWebService.php
- <?php
- class TestWebService
- {
- public function HelloWorld()
- {
- return array(HelloWorldResult=>Hello);
- }
- public function GetArray($args)
- {
- /*
- 注意,Web Service的方法在声明时至多一个参数,
- 可是在调用该方法时就必须传value1,value2两个参数。
- (这一点十分令人费解,我的理解是,在调用该方法时,系统把所有参数都放到一个对象里传过来的)
- */
- $value1 = $args->value1;
- $value2 = $args->value2;//这两句是获取真正的参数
- $arry = array($value1,$value2);
- //返回值也很特别,不是直接返回$arry,而是把它放到一个对象里再返回。
- return array(GetArrayResult=>$arry);
- }
- }
- //创建WebSevice实例
- $server = new SoapServer(TestWebService.wsdl);
- //指定类名
- $server->setClass(TestWebService);
- $server->handle();
- ?>
1-2)TestWebService.wsdl代码
- TestWebService.wsdl
- <?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://tempuri.org/ 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://tempuri.org/ xmlns:wsdl=http://schemas.xmlsoap.org/wsdl/>
- <wsdl:types>
- <s:schema elementFormDefault=qualified targetNamespace=http://tempuri.org/>
- <s:element name=HelloWorld>
- <s:complexType />
- </s:element>
- <s:element name=HelloWorldResponse>
- <s:complexType>
- <s:sequence>
- <s:element minOccurs=0 maxOccurs=1 name=HelloWorldResult type=s:string />
- </s:sequence>
- </s:complexType>
- </s:element>
- <s:element name=GetArray>
- <s:complexType>
- <s:sequence>
- <s:element minOccurs=0 maxOccurs=1 name=value1 type=s:string />
- <s:element minOccurs=0 maxOccurs=1 name=value2 type=s:string />
- </s:sequence>
- </s:complexType>
- </s:element>
- <s:element name=GetArrayResponse>
- <s:complexType>
- <s:sequence>
- <s:element minOccurs=0 maxOccurs=1 name=GetArrayResult type=tns:ArrayOfString />
- </s:sequence>
- </s:complexType>
- </s:element>
- <s:complexType name=ArrayOfString>
- <s:sequence>
- <s:element minOccurs=0 maxOccurs=unbounded name=string nillable=true type=s:string />
- </s:sequence>
- </s:complexType>
- </s:schema>
- </wsdl:types>
- <wsdl:message name=HelloWorldSoapIn>
- <wsdl:part name=parameters element=tns:HelloWorld />
- </wsdl:message>
- <wsdl:message name=HelloWorldSoapOut>
- <wsdl:part name=parameters element=tns:HelloWorldResponse />
- </wsdl:message>
- <wsdl:message name=GetArraySoapIn>
- <wsdl:part name=parameters element=tns:GetArray />
- </wsdl:message>
- <wsdl:message name=GetArraySoapOut>
- <wsdl:part name=parameters element=tns:GetArrayResponse />
- </wsdl:message>
- <wsdl:portType name=TestWebServiceSoap>
- <wsdl:operation name=HelloWorld>
- <wsdl:input message=tns:HelloWorldSoapIn />
- <wsdl:output message=tns:HelloWorldSoapOut />
- </wsdl:operation>
- <wsdl:operation name=GetArray>
- <wsdl:input message=tns:GetArraySoapIn />
- <wsdl:output message=tns:GetArraySoapOut />
- </wsdl:operation>
- </wsdl:portType>
- <wsdl:binding name=TestWebServiceSoap type=tns:TestWebServiceSoap>
- <soap:binding transport=http://schemas.xmlsoap.org/soap/http />
- <wsdl:operation name=HelloWorld>
- <soap:operation soapAction=http://tempuri.org/HelloWorld style=document />
- <wsdl:input>
- <soap:body use=literal />
- </wsdl:input>
- <wsdl:output>
- <soap:body use=literal />
- </wsdl:output>
- </wsdl:operation>
- <wsdl:operation name=GetArray>
- <soap:operation soapAction=http://tempuri.org/GetArray style=document />
- <wsdl:input>
- <soap:body use=literal />
- </wsdl:input>
- <wsdl:output>
- <soap:body use=literal />
- </wsdl:output>
- </wsdl:operation>
- </wsdl:binding>
- <wsdl:binding name=TestWebServiceSoap12 type=tns:TestWebServiceSoap>
- <soap12:binding transport=http://schemas.xmlsoap.org/soap/http />
- <wsdl:operation name=HelloWorld>
- <soap12:operation soapAction=http://tempuri.org/HelloWorld style=document />
- <wsdl:input>
- <soap12:body use=literal />
- </wsdl:input>
- <wsdl:output>
- <soap12:body use=literal />
- </wsdl:output>
- </wsdl:operation>
- <wsdl:operation name=GetArray>
- <soap12:operation soapAction=http://tempuri.org/GetArray style=document />
- <wsdl:input>
- <soap12:body use=literal />
- </wsdl:input>
- <wsdl:output>
- <soap12:body use=literal />
- </wsdl:output>
- </wsdl:operation>
- </wsdl:binding>
- <wsdl:service name=TestWebService>
- <wsdl:port name=TestWebServiceSoap binding=tns:TestWebServiceSoap>
- <soap:address location=http://localhost/phpmyadmin/ws/TestWebService.php />
- </wsdl:port>
- <wsdl:port name=TestWebServiceSoap12 binding=tns:TestWebServiceSoap12>
- <soap12:address location=http://localhost/phpmyadmin/ws/TestWebService.php />
- </wsdl:port>
- </wsdl:service>
- </wsdl:definitions>
WSDL的代码比较长,当方法很多时,手敲代码是不太可能的。有一个巧的办法,就是也用.NET实现一个不含真正方法体的Web Serivce,然后通过http://***/TestWebService.asmx?wsdl的方法生成wsdl代码文件。
关于WSDL文件,我要说明特别说明两点:
(1)soap:address结点是声明WebService的地址,在部署时要改成相应地址;
(2)一维数组的声明类型为ArrayOfType,字符串数组为ArrayOfString。如果Type不是简单类型,则Type需要另外声明。
2).NET客户端代码
先要添加Web引用,地址为WSDL文件的Http地址。
.NET调用PHP Web Service调用代码(C#)
- //初始化WebService
- localhost.TestWebService srv = new localhost.TestWebService();
- //调第一个方法
- string str = srv.HelloWorld();
- //调第二个方法
- string[] arry= srv.GetArray(string1,string2);
.NET调用PHP Web Service总结:
(一)PHP是一种弱类型语言,检查错误比较困难。array类型也与一般理解的数组不同,它也有类似Hashtable的用法。
(二)PHP Web Service方法的传入参数、返回值都至多有一个,因为真正调用时的参数和返回值,都是包装到一个对象中传送的。
(三)PHP Web Service也支持自定义类型和自定义类型数组等复杂类型,但不支持多组数组。
(四)若返回值需要是多张二维表时,我浅薄的以为,可以传化一组字符串数组传送,格式为
[表1行数],[表1列数],[表1列名1],[表1列名2],……[表1列名N],[表1中按行列存放的值]
[表2行数],[表2列数],[表2列名1],[表2列名2],……[表2列名N],[表2中按行列存放的值]……
[表M行数],[表M列数],[表M列名1],[表M列名2],……[表M列名N],[表2中按行列存放的值]
按顺序将上面[]中的内容串成字符串数组,效率还不错,我测试10000行240列的数据,我有现成编解代码,有兴趣的可以向我索取.
教程链接:http://www.phprm.com/frame/php1003365.html
随意转载~但请保留教程地址★