一.WSDL的基本概念
WSDL是一个用于精确描述Web服务的文档,WSDL文档是一个遵循WSDL-XML模式的XML文档。WSDL 文档将Web服务定义为服务访问点或端口的集合。在 WSDL 中,由于服务访问点和消息的抽象定义已从具体的服务部署或数据格式绑定中分离出来,因此可以对抽象定义进行再次使用。消息,指对交换数据的抽象描述;而端口类型,指操作的抽象集合。用于特定端口类型的具体协议和数据格式规范构成了可以再次使用的绑定。将Web访问地址与可再次使用的绑定相关联,可以定义一个端口,而端口的集合则定义为服务。
一个WSDL文档通常包含8个重要的元素,即definitions、types、import、message、portType、operation、binding、service元素。这些元素嵌套在definitions元素中,definitions是WSDL文档的根元素。
WSDL 服务进行交互的基本元素:
Types(消息类型):数据类型定义的容器,它使用某种类型系统(如 XSD)。
Message(消息):通信数据的抽象类型化定义,它由一个或者多个 part 组成。
Part:消息参数
PortType(端口类型):特定端口类型的具体协议和数据格式规范。,它由一个或者多个 Operation组成。
Operation(操作):对服务所支持的操作进行抽象描述,WSDL定义了四种操作:
1.单向(one-way):端点接受信息;
2.请求-响应(request-response):端点接受消息,然后发送相关消息;
3.要求-响应(solicit-response):端点发送消息,然后接受相关消息;
4.通知(notification ):端点发送消息。
二、完整的PHP代码
$wsdl='http://51.125.2.147:7201/tdxzsp/service/dataExchangeSdscdf?wsdl';
//实例化对象
try{
$options = array(
'exceptions'=>true,
'cache_wsdl'=>WSDL_CACHE_NONE
);
libxml_disable_entity_loader(false);//防止发生错误
$client=new SoapClient($wsdl,$options);//原生php或者tp3.1使用此写法
//$client=new \SoapClient($wsdl,$options);//例如TP3.2的命名空间写法
} catch (Exception $e) {
die(json_encode(array('stat'=>0, 'msg'=>'连接XX查询平台失败','data'=>$e))); }
$param1=array('secretKey'=>'2A257F24sdfdsfdAD93BxzczxcFF','dealcode'=>'2019010101010001');
$param1_json = json_encode($param1);
//var_dump($param1_json);
//接口方法。
try{
$ret1 = $client->getProcitemByDeal(array('in0'=>$param1_json));
var_dump($ret1->out);
} catch (Exception $e) {
die(json_encode(array('stat'=>0, 'msg'=>'连接成功,运行查询函数失败','data'=>$e))); } catch(SoapFault $f) {
die(json_encode(array('stat'=>0, 'msg'=>$f)));
}
//将XML数据转换成数组
$array=(array)$ret1;
三、重点讲解
1.web服务器。php必须开启soap扩展
然后重启服务器即可。
2.书写代码,总是返回以下错误
使用try{}cache{}捕获到以下错误
{"faultstring":"Not enough message parts were received for the operation.","faultcode":"soap:Client"}
3.开始调试
echo '<pre>';
print_r($client->__getFunctions());//列出当前SOAP所有的方法,参数和数据类型,也可以说是获得web service的接口
print_r($client->__getTypes());//列出每个web serice接口对应的结构体
echo '</pre>';
可以输出wsdl所提供的所有方法和方法对应参数对照,如图:
Array
(
[0] => getProcitemByDealResponse getProcitemByDeal(getProcitemByDeal $parameters)
)
Array
(
[0] => struct getProcitemByDeal {
string in0;
}
[1] => struct getProcitemByDealResponse {
string out;
}
)
可以看出,这个接口所接受的参数名为in0。所以重新构造了传输的参数内容
将
$ret1 = $client->getProcitemByDeal($param1_json);
改为了
$ret1 = $client->getProcitemByDeal(array('in0'=>$param1_json));
4.再次请求,显示出正确的返回内容。
5.特别注意:此次测试项目的接口端是java开发,返回的是xml数据。处理方式如下:
//转换成simplexml_load_string对象
$v=simplexml_load_string($ret1->out, 'SimpleXMLElement', LIBXML_NOCDATA);
$json_v = object_to_array($v);
这里要说明一下:获取返回值时,一定要使用$ret1->out。这个out我们再前面调试时就可以看到。
[1] => struct getProcitemByDealResponse {
string out;
}
调用了一个自定义的方法
/**
* 对象 转 数组
*
* @param object $obj 对象
* @return array
*/
function object_to_array($obj) {
$obj = (array)$obj;
foreach ($obj as $k => $v) {
if (gettype($v) == 'resource') {
return;
}
if (gettype($v) == 'object' || gettype($v) == 'array') {
$obj[$k] = (array)object_to_array($v);
}
}
return $obj;
}
将返回的xml经过处理后直接转换为php语言可用的数组结构。我们使用这句代码数据查看即可:
echo '<pre>';
var_dump($json_v);
echo '</pre>';
好了,剩下的就是基础知识可以解决的了。感谢大家的查看。转发请注明出处,谢谢!!!