呼…才发现很久没发博客了,真的实在是太忙了。平时还要抽点时间维护http://bbs.mudbest.com 。
平时很少写webService,一般都是需要给第三方提供接口的时候才去写。偶然的一个机会,打开了项目里现有的webService文件,发现前人所写的webService都是以简单的创建一个类,再将类里面的函数暴露给第三方调用,连WSDL都不支持,这就不是规范的webService接口定义了。
开发人员应该都知道,传统的webService是有wsdl支持的,就是介绍了,传入和返回,以及webService的一些基本结构介绍信息,这能很大限度的增加接口可读性和参考性。希望所有开发者能够自我养成良好的编码习惯,开发者最忌讳的就是怕麻烦,请尊重自己的职业。
服务端demo:
http://help.mudbest.com/php/demo_nusoap/webService/RefundService.php
http://help.mudbest.com/php/demo_nusoap/webService/RefundService.php?wsdl
下面nusoap的服务端(webService)和客户端(client)介绍一下简单实例。
nusoap支持类库下载地址:http://www.mudbest.com/webservicephp%E7%9A%84soap%E4%B8%8Enusoap%E6%9C%8D%E5%8A%A1%E7%AB%AF%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF%E7%9A%84%E9%80%9A%E4%BF%A1/nusoap-0-9-5/
1、首先创建一个服务端:
这里用的是注册类,而不是注册函数,建议创建webService的时候将服务结构整理清晰。
class.refundStatusService.php
<?php /** * 退票状态回显服务类库 * @author hkshadow */ class refundStatusService{ private $objDb = null; public function __construct(){ } public function connect(){ } public function hello($person, $interface){ $greeting = 'Hello111, ' . $person ['firstname'] . '. It is nice to meet a ' . $person ['age'] . ' year old ' . $person ['gender'] . '.' . $interface ['type']; $winner = 'Scott'; //要返回的数据 return array ('greeting' => $greeting, 'winner' => $winner ); } } ?>
建立服务(例如地址http://www.mudbest.com/webService.php)
require_once('comm/nusoap/nusoap.php'); require_once('webservice/RefundStatusService.php'); // 新建一个soap服务 $server = new soap_server (); // 初始化支持wsdl $server->configureWSDL ( 'hellowsdl2', 'urn:hellowsdl2' ); //设置返回时的编码 $server->soap_defencoding = 'UTF-8'; //是否utf8_decode() $server->decode_utf8 = false; //设置传入的编码 $server->xml_encoding = 'UTF-8'; // 定义接收的数据结构 $server->wsdl->addComplexType ( 'Person', 'complexType', 'struct', 'all', '', //array ('type' => '1==2' ); array ('type' => array ('name' => 'type', 'type' => 'xsd:string' ) ), // 后面的type定义数据的类型,这个是string array ('firstname' => array ('name' => 'firstname', 'type' => 'xsd:string' ), // 后面的type定义数据的类型,这个是string 'age' => array ('name' => 'age', 'type' => 'xsd:int' ), // 后面的type定义数据的类型,这个是int 'gender' => array ('name' => 'gender', 'type' => 'xsd:string' ) ) // 后面的type定义数据的类型,这个是string ); //定义返回数据结构 $server->wsdl->addComplexType ( 'SweepstakesGreeting', 'complexType', 'struct', 'all', '', array ('greeting' => array ('name' => 'greeting', 'type' => 'xsd:string' ), 'winner' => array ('name' => 'winner', 'type' => 'xsd:string' ) ) ); /** 备注: array ('person' => 'tns:Person' ) 这里声明是根据addComplexType ('Person')方法定义属性,如果只需要传入字符串,则直接xsd:string即可 // 定义接收的数据结构 $server->wsdl->addComplexType ( 'Person', 'complexType', 'struct', 'all', '', //array ('type' => '1==2' ); array ('type' => array ('name' => 'type', 'type' => 'xsd:string' ) ), // 后面的type定义数据的类型,这个是string array ('firstname' => array ('name' => 'firstname', 'type' => 'xsd:string' ), // 后面的type定义数据的类型,这个是string 'age' => array ('name' => 'age', 'type' => 'xsd:int' ), // 后面的type定义数据的类型,这个是int 'gender' => array ('name' => 'gender', 'type' => 'xsd:string' ) ) // 后面的type定义数据的类型,这个是string ); ----------------------------------------------------- array ('return' => 'tns:SweepstakesGreeting' ) 这里声明是根据addComplexType ('SweepstakesGreeting')方法定义属性,如果只需要返回字符串,则直接xsd:string即可 //定义返回数据结构 $server->wsdl->addComplexType ( 'SweepstakesGreeting', 'complexType', 'struct', 'all', '', array ('greeting' => array ('name' => 'greeting', 'type' => 'xsd:string' ), 'winner' => array ('name' => 'winner', 'type' => 'xsd:string' ) ) ); */ // 服务器定义的soap调用方法 $server->register ( 'refundStatusService.hello', // 这里注册的是类,类文件class.refundStatusService.php array ('person' => 'tns:Person' ), // 客户端传来的变量 array ('return' => 'tns:SweepstakesGreeting' ), // 返回参数 'urn:hellowsdl2', // soap名 'urn:hellowsdl2#hello', // soap的方法名 'rpc', // 使用的方式 'encoded', // 编码 'test'// 存档 ); //请求时(试图)调用服务 //$HTTP_RAW_POST_DATA = isset ( $HTTP_RAW_POST_DATA ) ? $HTTP_RAW_POST_DATA : ''; $HTTP_RAW_POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : ''; //处理请求并且返回响应结果(processes request and returns response) $server->service ( $HTTP_RAW_POST_DATA );
至此服务端已经创建完成,接下来要做的便是客户端(client)了。
demo.php
// 包函nusoap.php require_once(comm/nusoap/nusoap.php'); // 新建一个soap客户端,调用服务端提供的wsdl // $client = new soapclient('http://www.mudbest.com/webService.php?wsdl', true); $client = new nusoap_client ( 'http://www.mudbest.com/webService.php' ); // 查看一下是不是报错 $err = $client->getError (); if ($err) { // 显示错误 echo '<h2>Constructor error</h2><pre>' . $err . '</pre>'; } // 要向服务端要传的参数 $interface = array ('type' => '1==2' ); $person = array ('firstname' => 'Willi', 'age' => 22, 'gender' => 'male' ); // 调用服务端的方法(这里注意call的名字与regisert名一样) $result = $client->call ( 'refundStatusService.hello', array ('userInfo' => $person, 'interfaceType' => $interface ) ); //WSDL调用服务端的方法(这里注意call的名字与regisert名一样) //$result = $client->call ( 'refundStatusService.hello'); // 错误审核 if ($client->fault) { echo '<h2>Fault</h2><pre>'; print_r ( $result ); echo '</pre>'; } else { $err = $client->getError (); if ($err) { echo '<h2>Error</h2><pre>' . $err . '</pre>'; } else { echo '<h2>Result</h2><pre>'; print_r ( $result ); echo '</pre>'; } } // 显示请求信息 echo '<h2>Request</h2>'; echo '<pre>' . htmlspecialchars ( $client->request, ENT_QUOTES ) . '</pre>'; // 显示返回信息 echo '<h2>Response</h2>'; echo '<pre>' . htmlspecialchars ( $client->response, ENT_QUOTES ) . '</pre>'; // 显示调试信息 echo '<h2>Debug</h2>'; echo '<pre>' . htmlspecialchars ( $client->debug_str, ENT_QUOTES ) . '</pre>';
到这里,服务端以及客户端已经创建完成。
当在浏览器上浏览http://www.mudbest.com/webService.php时会出现结构图。
当在浏览器上浏览http://www.mudbest.com/webService.php?wsdl时会出现xml格式。
我把你的方法整合到Yii框架时,报
Error
Response not of type text/xml: text/html
能解答一下吗?
Debug
2014-08-12 16:09:37.480720 nusoap_client: ctor wsdl= timeout=0 response_timeout=30
endpoint=string(66) “http://localhost/allApi/ympapi/ympapi/index.php/YWS/SericeWeb?wsdl”
2014-08-12 16:09:37.480767 nusoap_client: instantiate SOAP with endpoint at http://localhost/allApi/ympapi/ympapi/index.php/YWS/SericeWeb?wsdl
2014-08-12 16:09:37.480803 nusoap_client: call: operation=WebServiceClientController.callTest, namespace=http://tempuri.org, soapAction=, rpcParams=, style=rpc, use=encoded, endpointType=soap
params=array(2) {
[“userInfo”]=>
array(3) {
[“firstname”]=>
string(5) “Willi”
[“age”]=>
int(22)
[“gender”]=>
string(4) “male”
}
[“interfaceType”]=>
array(1) {
[“type”]=>
string(4) “1==2”
}
}
headers=bool(false)
2014-08-12 16:09:37.480844 nusoap_client: serializing param array for operation WebServiceClientController.callTest
2014-08-12 16:09:37.480863 nusoap_client: in serialize_val: name=userInfo, type=, name_ns=, type_ns=, use=encoded, soapval=
value=array(3) {
[“firstname”]=>
string(5) “Willi”
[“age”]=>
int(22)
[“gender”]=>
string(4) “male”
}
attributes=bool(false)
2014-08-12 16:09:37.480914 nusoap_client: serialize_val: serialize struct
2014-08-12 16:09:37.480935 nusoap_client: in serialize_val: name=firstname, type=, name_ns=, type_ns=, use=encoded, soapval=
value=string(5) “Willi”
attributes=bool(false)
2014-08-12 16:09:37.480960 nusoap_client: serialize_val: serialize string
2014-08-12 16:09:37.480982 nusoap_client: serialize_val returning Willi
2014-08-12 16:09:37.480998 nusoap_client: in serialize_val: name=age, type=, name_ns=, type_ns=, use=encoded, soapval=
value=int(22)
attributes=bool(false)
2014-08-12 16:09:37.481019 nusoap_client: serialize_val: serialize int
2014-08-12 16:09:37.481033 nusoap_client: serialize_val returning 22
2014-08-12 16:09:37.481048 nusoap_client: in serialize_val: name=gender, type=, name_ns=, type_ns=, use=encoded, soapval=
value=string(4) “male”
attributes=bool(false)
2014-08-12 16:09:37.481070 nusoap_client: serialize_val: serialize string
2014-08-12 16:09:37.481087 nusoap_client: serialize_val returning male
2014-08-12 16:09:37.481100 nusoap_client: serialize_val returning Willi22male
2014-08-12 16:09:37.481116 nusoap_client: in serialize_val: name=interfaceType, type=, name_ns=, type_ns=, use=encoded, soapval=
value=array(1) {
[“type”]=>
string(4) “1==2”
}
attributes=bool(false)
2014-08-12 16:09:37.481144 nusoap_client: serialize_val: serialize struct
2014-08-12 16:09:37.481160 nusoap_client: in serialize_val: name=type, type=, name_ns=, type_ns=, use=encoded, soapval=
value=string(4) “1==2”
attributes=bool(false)
2014-08-12 16:09:37.481180 nusoap_client: serialize_val: serialize string
2014-08-12 16:09:37.481197 nusoap_client: serialize_val returning 1==2
2014-08-12 16:09:37.481210 nusoap_client: serialize_val returning 1==2
2014-08-12 16:09:37.481224 nusoap_client: wrapping RPC request with encoded method element
2014-08-12 16:09:37.481243 nusoap_client: In serializeEnvelope length=339 body (max 1000 characters)=Willi22male1==2 style=rpc use=encoded encodingStyle=http://schemas.xmlsoap.org/soap/encoding/
2014-08-12 16:09:37.481255 nusoap_client: headers:
bool(false)
2014-08-12 16:09:37.481272 nusoap_client: namespaces:
array(0) {
}
2014-08-12 16:09:37.481300 nusoap_client: endpoint=http://localhost/allApi/ympapi/ympapi/index.php/YWS/SericeWeb?wsdl, soapAction=, namespace=http://tempuri.org, style=rpc, use=encoded, encodingStyle=http://schemas.xmlsoap.org/soap/encoding/
2014-08-12 16:09:37.481315 nusoap_client: SOAP message length=736 contents (max 1000 bytes)=Willi22male1==2
2014-08-12 16:09:37.481337 nusoap_client: transporting via HTTP
2014-08-12 16:09:37.481534 nusoap_client: sending message, length=736
2014-08-12 16:09:37.481377 soap_transport_http: ctor url=http://localhost/allApi/ympapi/ympapi/index.php/YWS/SericeWeb?wsdl use_curl= curl_options:
array(0) {
}
2014-08-12 16:09:37.481404 soap_transport_http: parsed URL scheme = http
2014-08-12 16:09:37.481418 soap_transport_http: parsed URL host = localhost
2014-08-12 16:09:37.481431 soap_transport_http: parsed URL path = /allApi/ympapi/ympapi/index.php/YWS/SericeWeb
2014-08-12 16:09:37.481442 soap_transport_http: parsed URL query = wsdl
2014-08-12 16:09:37.481466 soap_transport_http: set header Host: localhost
2014-08-12 16:09:37.481488 soap_transport_http: set header User-Agent: NuSOAP/0.9.5 (1.123)
2014-08-12 16:09:37.481506 soap_transport_http: set header Content-Type: text/xml; charset=ISO-8859-1
2014-08-12 16:09:37.481520 soap_transport_http: set header SOAPAction: “”
2014-08-12 16:09:37.481552 soap_transport_http: entered send() with data of length: 736
2014-08-12 16:09:37.481569 soap_transport_http: connect connection_timeout 0, response_timeout 30, scheme http, host localhost, port 80
2014-08-12 16:09:37.481596 soap_transport_http: calling fsockopen with host localhost connection_timeout 0
2014-08-12 16:09:37.482825 soap_transport_http: set response timeout to 30
2014-08-12 16:09:37.482859 soap_transport_http: socket connected
2014-08-12 16:09:37.482896 soap_transport_http: set header Content-Length: 736
2014-08-12 16:09:37.482919 soap_transport_http: HTTP request: POST /allApi/ympapi/ympapi/index.php/YWS/SericeWeb?wsdl HTTP/1.0
2014-08-12 16:09:37.482935 soap_transport_http: HTTP header: Host: localhost
2014-08-12 16:09:37.482948 soap_transport_http: HTTP header: User-Agent: NuSOAP/0.9.5 (1.123)
2014-08-12 16:09:37.482961 soap_transport_http: HTTP header: Content-Type: text/xml; charset=ISO-8859-1
2014-08-12 16:09:37.482973 soap_transport_http: HTTP header: SOAPAction: “”
2014-08-12 16:09:37.482986 soap_transport_http: HTTP header: Content-Length: 736
2014-08-12 16:09:37.483389 soap_transport_http: wrote data to socket, length = 936
2014-08-12 16:09:37.538893 soap_transport_http: read line of 36 bytes: HTTP/1.0 500 Internal Server Error
2014-08-12 16:09:37.538954 soap_transport_http: read line of 37 bytes: Date: Tue, 12 Aug 2014 08:09:37 GMT
2014-08-12 16:09:37.538990 soap_transport_http: read line of 56 bytes: Server: Apache/2.4.4 (Win32) OpenSSL/0.9.8y PHP/5.4.19
2014-08-12 16:09:37.539023 soap_transport_http: read line of 26 bytes: X-Powered-By: PHP/5.4.19
2014-08-12 16:09:37.539056 soap_transport_http: read line of 19 bytes: Connection: close
2014-08-12 16:09:37.539087 soap_transport_http: read line of 25 bytes: Content-Type: text/html
2014-08-12 16:09:37.539118 soap_transport_http: read line of 2 bytes:
2014-08-12 16:09:37.539153 soap_transport_http: found end of headers after length 201
2014-08-12 16:09:37.539220 soap_transport_http: want to read content to EOF
2014-08-12 16:09:37.539328 soap_transport_http: read buffer of 8192 bytes
2014-08-12 16:09:37.542961 soap_transport_http: read buffer of 3250 bytes
2014-08-12 16:09:37.543140 soap_transport_http: read buffer of 5339 bytes
2014-08-12 16:09:37.547216 soap_transport_http: read buffer of 1682 bytes
2014-08-12 16:09:37.547397 soap_transport_http: read buffer of 0 bytes
2014-08-12 16:09:37.547419 soap_transport_http: read to EOF
2014-08-12 16:09:37.547433 soap_transport_http: read body of length 18463
2014-08-12 16:09:37.547455 soap_transport_http: received a total of 18664 bytes of data from server
2014-08-12 16:09:37.547665 soap_transport_http: closed socket
2014-08-12 16:09:37.547694 soap_transport_http: No Content-Encoding header
2014-08-12 16:09:37.547712 soap_transport_http: end of send()
2014-08-12 16:09:37.547742 nusoap_client: got response, length=18463 type=text/html
2014-08-12 16:09:37.547758 nusoap_client: Entering parseResponse() for data of length 18463 headers:
array(5) {
[“date”]=>
string(29) “Tue, 12 Aug 2014 08:09:37 GMT”
[“server”]=>
string(46) “Apache/2.4.4 (Win32) OpenSSL/0.9.8y PHP/5.4.19”
[“x-powered-by”]=>
string(10) “PHP/5.4.19”
[“connection”]=>
string(5) “close”
[“content-type”]=>
string(9) “text/html”
}
2014-08-12 16:09:37.547800 nusoap_client: Error: Response not of type text/xml: text/html