+ -
当前位置:首页 → 问答吧 → [纯属原创]PHP WebService 之 SOAP WSDL....邪恶~~~

[纯属原创]PHP WebService 之 SOAP WSDL....邪恶~~~

时间:2009-06-16

来源:互联网

....绝了~~研究了5天~~~ 尝试过了 nusoap HTTP方式传送XML php5自带....
其中nusoap 和 HTTP方式的,经过测试即使XML的内容一致,还是得不到结果~~~痛苦啊~~~

PHP5自带的~~我经过试验,还是不对~返回空~~~为什么呢~~~研究啊~研究~~~后来发现了~~~文档中比较特别的  SOAPHeader.....太邪恶了~~头~~~怎么发布呢~~搜搜啊~~~~

结果我发现百度能力太弱了,于是我转向了GOOGLE发现了不少好文章~~可惜由于着急~~没仔细研究~~错漏了一篇精华~~~

http://www.nabble.com/WSDL-SOAP-header-td14405645.html

国外太牛了~很详细的教学~~而我呢~太不仔细了~~没看出特别的header问题~~~

来看看~~吧~~如何操作~~~

假如有如下的一个需求~~~提供的XML格式哈~~~先来简单的<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:adm="http://admin.phptext.net">
   <soapenv:Header>
       <adm:username>MoHock</adm:username>
   </soapenv:Header>
   <soapenv:Body>
      <adm:siteinfo>
         <adm:domainname>www.phptext.net</adm:domainname>
         <adm:sitename>PHPText.Net</adm:sitename>
         <adm:class>技术类</adm:class>
      </adm:siteinfo>
   </soapenv:Body>
</soapenv:Envelope>
头大吧~~~可是对方技术就给我这么一个文档,里面没有说什么变量函数,就是一个XML,然后说需要的参数,比如上面这个就有:
username , domainname , sitename , class
呵呵怎么发送呢~~~

按照nusoap就会通过相应函数操作后,输出一个和上面的类似的一个XML文件通过HTTP传输....
HTTP方式就不用说了吧~XML文件自己写。。。
PHP5自带的就不用。。。。

不过呢~~前2个方式的操作之后,你会发现XML地方少了 adm:username ...等等 都少了 adm:
没错~~这个也被我认为的一个可能~于是nusoap 我加上了~~结果还是无功~~~

正头疼时,发现 header body 之分~~于是开始找这个原因~~于是我发现了 nusoap 有header函数~~~
于是~~我加上了~~郁闷的是~~又无效了~~~

于是啊~~就有了上网查,找网友帮忙的经历~~~其中要特别感谢

PHPRPC技术交流群 (48855729)
膘叔 www.neatstudio.com
携剑看山

以及网友
Coolfire
[木頭] www.loopx.cn

等大力支持~~~

好回到正题~~~那么这里我只讲有用的 PHP5自带的SOAP类~~~如何按照上面的XML发送....

首先我们看看基本的 SOAP代码//建立客户端链接
$soapClient = new SoapClient('http://test.phptext.net/services/?wsdl');

//设置函数参数
$param  = array('ags'=>'123456');

//调用参数
$result = $soapClient->test($param);

//查看返回结果
print_r($result);
上面的代码可以应付 只有body的~~~而其中 $soapClient->test() 则是服务器中的一个函数提供的。

比如我们上文提到的   <soapenv:Body>
      <adm:siteinfo>
         <adm:domainname>www.phptext.net</adm:domainname>
         <adm:sitename>PHPText.Net</adm:sitename>
         <adm:class>技术类</adm:class>
      </adm:siteinfo>
   </soapenv:Body>
这里面就可以调用 siteinfo() 函数。而 $param 参数的内容是。array(
'domainname'=>'www.phptext.net',
'sitename'=>'PHPText.Net',
'class'=>'技术类',
);
不过注意下顺序~~~群里高手说~PHP对SOAP支持不是很好,数组的顺序可能造成失败~~~

这样基本的就OK了~但是header怎么做呢 呵呵有 soapheader 类呢~~~
看看如何弄的~~就那上文的~~   <soapenv:Header>
       <adm:username>MoHock</adm:username>
   </soapenv:Header>
依照这个看看soap的方式//生成头
$headers = new SoapHeader('http://admin.phptext.net','username','MoHock');
//设置客户端调用函数发送的头
$soapClient->__setSoapHeaders(array($headers));
其中 SoapHeader 的第一个参数,是命名空间,取决于第一行的设置:<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:adm="http://admin.phptext.net">
怎样现在明白了~为什么没有adm的~~因为定义了~~嘎嘎~~~
这样就是简单的格式了~~如果复杂的呢~~比如~~~<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:adm="http://admin.phptext.net">
   <soapenv:Header>
     <adm:userinfo>
       <adm:username>MoHock</adm:username>
       <adm:useremail>[email protected]</adm:useremail>
     </adm:userinfo>
  </soapenv:Header>
   <soapenv:Body>
      <adm:sitelist>
         <adm:siteinfo>
            <adm:domainname>www.phptext.net</adm:domainname>
            <adm:sitename>PHPText.Net</adm:sitename>
         </adm:siteinfo>
         <adm:class>技术类</adm:class>
      </adm:sitelist>
  </soapenv:Body>
</soapenv:Envelope>
怎样~~~有参数多了吧~~其实没什么就是一个二维数组....
看看头的//生成头
$data    = array('username'=>'MoHock','useremail'=>'[email protected]');
$headers = new SoapHeader('http://admin.phptext.net','userinfo',$data);
头的就是这样,更多维就继续嵌套,但是最外围的 userinfo 只能作为名称就OK。

看看BODY的$siteinfo = array('domainname'=>'www.phptext.net','sitename'=>'PHPText.Net');
$data     = array(
'siteinfo'=>$siteinfo,
'class'=>'技术类'
);
$result = $soapClient->sitelist($data);
怎样能看明白不~~~呵呵~这样就是多维的了~~~
不管header,或者 body 他们之下的第一个则是 定死的东西.....

不需要数组~~~

另外就是 不管是设置头,还是调用函数,他们的参数都是用 数组组合的~~

-_-文采不好~别见怪~~不懂下面问~~或者加我~~

再介绍2个实用的soap客户端方法:$functions = $soapClient->__getFunctions();
print_r($functions);

$types = $soapClient->__getTypes();
print_r($types);
这个东西自己留意哦~~~呵呵 

第一个就是列出所有可用的方法
第二个是列出所有的方法类型~~

非常好用~~

不过如果对方一样提供了XML那么直接看body中的第一个元素就知道是哪个了~~比如上面提到的~~   <soapenv:Body>
      <adm:sitelist>
         <adm:siteinfo>
            <adm:domainname>www.phptext.net</adm:domainname>
            <adm:sitename>PHPText.Net</adm:sitename>
         </adm:siteinfo>
         <adm:class>技术类</adm:class>
      </adm:sitelist>
  </soapenv:Body>
函数自然就是:sitelist 嘎嘎~很简单吧~~

谷歌比百度强大~~支持谷歌一下~~

好像还有些什么~~忘记了~~以后想起再说吧~~~嘎嘎写了不少~纯属原创~~

作者: MoHock   发布时间: 2009-06-16

占位,以后再研究

作者: hotwow   发布时间: 2009-06-16

感觉很乱...
看清一句[code]谷歌比百度强大~~支持谷歌一下~~[/code]

作者: Alog_W   发布时间: 2009-06-17