问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

PHP如何调用webservice

发布网友 发布时间:2022-04-07 09:22

我来回答

2个回答

懂视网 时间:2022-04-07 13:43

0x00 前言

近期一直在写接口,在此之前接口数据传输都是使用json或者xml格式进行传输或获取的。但这次和第三方联调时,他们给予的是wsdl格式。瞬间秒变SB...

google到测试用code,测试调用第三方接口返回状态200。以为没啥事了可以就此结束了,跟近后才发现,不管怎么调用他们接口就是没有正确的数据回显。随后他们那边查看log后发现,压根传过去的参数他们没有接收到,懵逼了一下午到晚上才解决了这个问题。觉得挺有意思的,所以记下来先。

0x01 wsdl是什么

综合某度上所说,它就是一个xml格式的文档,用于描述Web Server的定义,也就是说是一个Web Server方法及参数说明。

当我们请求http://api.test.cn/xwebservices/testServer?wsdl',类似这种结尾是?wsdl的URL时,会一坨xml结构的数据给你。

没错,就是一坨...

28421c3fc7d991f4c4487b03993a819.png

接下来,怎么看懂它和它所说的方法才是关键,其它都是白搭。

0x02 理解描述文档

刚开始看这个xml文档时是比较懵逼的,但用PHP的扩展处理下就明显很多了。

<?php
$client = new SoapClient('http://api.test.cn/xwebservices/testServer?wsdl');
print "
提供的方法
";
print_r($client->__getFunctions());
print "相关的数据结构
";
print_r($client->__getTypes());
print "

";

05653125ef9f7976837243150044a23.png

这里我们用到了SOAP扩展,这个扩展是PHP官方文案中出示操作处理WebServer服务扩展,最终我们也是通过它来实现参数传输。

在上面的图片中可以理解出,这个接口提供了三个方法,分别是:

● xxxxUserInfo

● xxxxResumeNum

● download**

相关的数据机构则是指方法中参数名称,及参数类型。比如xxxxUserInfo方法,需要三个string类型的参数。分别对应in0,in1和in2。

此处的传参数key必然是in0,也就是一个无需数组,用户自定义或双方约定好的任意参数名称。在开始写接口方法的时候,我是根据接口文案中给予的参数说明如:err_msg(表示错误信息),err_code(表示错误编码),date(传输的最终数据)进行传输的。后改为有序数组,挨个填入对应参数,此时key就是的0到2。可试过之后还是没什么卵用,最终包着试一试的心态,尝试一下将int0作为键名,对应的err_msg内容作为值。ok~,完美解决。

Code:

<?php
/**
 * @author 0x584A
 * 获取WSDL接口数据
 */
class getwsdlTest extends PHPUnit_Framework_TestCase
{
 public $apiurl = 'http://api.test.cn/xwebservices/testServer?wsdl';
 private static $soapClientHandler;
 private $infoArr = [
 'err_msg' => 'false',
 'err_code' => '0',
 'date' => '此处是要传输的数据'
 ];
 public function setUp()
 {
 $client = new SoapClient('http://api.test.cn/xwebservices/testServer?wsdl');
 print "提供的方法
";
 print_r($client->__getFunctions());
 print "相关的数据结构
";
 print_r($client->__getTypes());
 print "

";
 }
 /**
 * xxxxUserInfo方法
 */
 public function testxxxxUserInfoData()
 {
 try {
  $ApiInfo = $this->infoArr;
  //set request param
  $parameter = array(
  'in0' => $ApiInfo['err_msg'],
  'in1' => $ApiInfo['err_code'],
  'in2' => $ApiInfo['date']
  );
  $result = $this->getSoapClientHandler()->synchUserInfo($parameter);
  //调用结果返回异常
  if (!$result instanceof stdClass) {
  throw new Exception("调用synchUserInfo结果出现异常:" . json_encode($result));
  }
  //调用接口状态码,输出对应错误详情
  if ($result->out == '01') {
  throw new Exception("调用synchUserInfo=>error:" . $result->out . ",msg:接口数据异常");
  }
  $xml_parser = xml_parser_create();
  if (!xml_parse($xml_parser, $result->out, true)) {
  xml_parser_free($xml_parser);
  throw new Exception("调用synchUserInfo返回的不是一个xml结构体");
  }
  xml_parser_free($xml_parser);
  //XXE
  libxml_disable_entity_loader(true);
  $xml = simplexml_load_string($result->out, 'SimpleXMLElement', LIBXML_NOCDATA);
  // 输出参数
  var_dump($xml->data);
  echo " 成功".PHP_EOL;
 } catch (SoapFault $soapFault) {
  throw new Exception($soapFault->getMessage() . $this->getSoapClientHandler()->__getLastResponse());
 }
 }
 /**
 * @description getSoapClientHandler
 */
 public function getSoapClientHandler()
 {
 if (!self::$soapClientHandler) {
  self::$soapClientHandler = new SoapClient($this->getSynchApi());
 }
 return self::$soapClientHandler;
 }
 /**
 * @description getSynchApi
 */
 public function getSynchApi()
 {
 return $this->apiurl;
 }
}
?>

推进:《PHP教程》

热心网友 时间:2022-04-07 10:51

最近工作中需要用php调用web service接口,对php不熟,上网搜搜,发现关于用php调用web service的文章也不多,不少还是php4里用nusoap这个模块调用的方法,其实php5里已经包含了处理soap的模块,但是资料太少了,上php官网上查帮助,写的不是很容易理解,经过多次实践,终于搞清楚了,php调用web service还是非常简单的。下面用一个例子说明:
web service服务是查询QQ用户是否在线
使用php5开发客户端:
<?php
try {
    //$client = new SoapClient("HelloService.wsdl",array('encoding'=>'UTF-8'));
    $client = new SoapClient("webservices/qqOnlineWebService.asmx?wsdl");
  var_mp($client->__getFunctions());
  print("<br/>");
  var_mp($client->__getTypes());
  print("<br/>");

class qqCheckOnline{
 var $qqCode = "10000";
};
$arrPara = array(new qqCheckOnline);

  $arrResult = $client->__Call("qqCheckOnline",$arrPara);//$client->qqCheckOnline($arrPara);
  
  echo $arrResult->qqCheckOnlineResult . "<br/>";
} catch (SOAPFault $e) {
    print $e;
}
?>
代码确实很简单吧,创建SoapClient对象时,可以使用保存在本地WSDL文件,也可以使用远程的地址,后面的array数组里可以带上很多的参数,具体参数可以查php的SoapClient帮助,这里带的是字符集编码,如果调用方法的参数里有中文,一定要指定字符集编码,否则会出错。
调用web service前可以先调用SoapClient的__geunctions()和__getTypes()方法看一下你要调用的web service暴露的方法,参数和数据类型,需要注意的是传入的参数名一定要和soapclient里面定义的一致,否则参数是传不过去的。
需要使用SoapClient的__soapCall()或__call()方法,具体使用方法可以查php的帮助文档。如果参数要求是一个结构体,请用类代替,如上面的代码。
另外发现个问题,如果web service方法返回的是xml格式的字符串,php接收到以后会自己把数据内容解析出来,而不是xml字符串.

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
备忘录在手机的哪里 刚性消费有哪些 中国经济快速增长的原因 什么是刚性消费 什么叫刚性增长 特别精辟的个性签名(非常经典的个性句子) 特别经典的个性签名(非常惊艳的个性句子) 文艺范十足的个性签名(温柔治愈的个性签名句子) wps文字怎么设置每页头和尾 27岁的女人需要补充哪些营养元素 电脑网易云音乐外放为什么变小 梦见自己吃苹果,而愁人也死了是什么意思? 昨晚做梦梦到自己吃苹果快吃完了,低头一看,剩的一点苹果上有一个小小的虫子,再用手机扣扣牙齿,扣一个 梦见和上小学的朋友偷别人的葡萄吃,我吃了两个还是酸的 我的手机号被标记为!疑是诈骗!怎么办 为什么发邮政信息到手机的号码被人标记诈骗,这对我的银行卡有危险吗 用自己身份证办的手机卡被多次标记诈骗对自己有影响么 本人身份证办的手机卡被标记诈骗对身份证有什么影响 手机号码被局方停机标记成诈骗对身份证有影响吗? 手机号被莫名标记诈骗,怎么办?有影响吗? 手机卡被人标记诈骗,对本人信用贷款有影响吗 手机卡被反诈骗封停,有什么后果 我的电话号码,被别人标记为诈骗电话,这个怎么办呢,有没有危害危害? 没变,换手机后微信部分联系人丢失怎么办? php怎么读取 java写的wsdl文档 如何激活12306账号 如何激活12306账号? 读书笔记格式 所读部分大意概括:(50字左右)精彩句段摘抄:(400字左右) 赏读推荐理由:(100字左右) 麦田里的守望者 俗世奇人的读书笔记 两本书 不要读后感 怎么做 俗世奇人 的读书卡 周公解梦梦见爸爸下雨天触电死了 梦见亲人遭电击了是凶,还是吉兆 做梦梦到自己的爸爸被电死了又死 做梦梦到父亲在外面接电被电死了,突然觉得太难受了,不知道这个梦何解。我现在没有对象,接着又梦到好像 edius输出高清格式的视频 用那种输出器会比较好?最清晰... 梦见已故父亲被电线缠身 steam串流 鼠标消失 梦见我爸爸被电死了,,这是什么意思? 在steam上买的游戏 打开游戏后鼠标点击没反应,求解决办法 我在steam上联机打的 进入游戏后 键盘鼠标失灵 梦见父亲被劫.生死不明 一打开steam鼠标就失灵 Steam游戏内充值鼠标没反应 我用Steam在mac上玩DOTA2但是鼠标失灵怎么办 打开steam看好友资料,或者玩dota2 鼠标失灵 steam服务器按了连接无反应?点击详解↓ steamlink鼠标右键是什么 千万里我追寻着你是什么歌? 孟姜女千里寻夫的意义 众里寻他千百度,蓦然回首,那人却在灯火阑珊处.这话是什么意思??_百度知...