首页 > 代码库 > PHP中调用Soap/WebService

PHP中调用Soap/WebService

关于在PHP中如何调用Soap/WebService的描述,网络上有不少帖子。但是主要讲述了如何用PHP开发服务器端、客户端并加以关联,而很少触及在PHP中调用现成的WebService的情况。在本文中我们做一个简单的示范。

 

一、寻找WebService来源

WebService可以自己编写,但是也可以从网络上去寻找现成的。我用的是www.xmethods.net里的US Zip Validator。它的WSDL文件位置在:http://www.webservicemart.com/uszip.asmx?WSDL。 它的作用是根据输入的ZIP代码,返回该代码对应的美国地名,州名,经纬度等。

二、创建SoapClient

第二步就是创建SoapClient,并调用WebService中的方法,并获得返回值。PHP代码如下:

$objSoapClient = new SoapClient("http://www.webservicemart.com/uszip.asmx?WSDL");$param=array("ZipCode"=>$zip);$out=$objSoapClient->ValidateZip($param);$data=$out->ValidateZipResult; 

SoapClient的创建有好多方法,我们用的是最标准的(也是最简单的)WSDL方法。由于查询ZIP的方法肯定需要一个参数,所以我们必须创建一个数组,用“参数名=>取值”的方式进行赋值。

也许读者会对这个数组的创建有一定的兴趣。比如,我们怎么知道“参数名”应该是“ZipCode”而不是别的什么呢?为什么没有更多的参数了,而只有一个?OK,这个问题我们稍后解释。因为这牵涉到WSDL的解读。

创建好参数后,同样的,我们调用SoapClient的方法ValidateZip,并传递参数进去;对于返回的结果,我们用$data变量取出我们真正感兴趣的东西。同样的,这里也存在方法名称是如何确定的问题。我们也在稍后介绍。

如果你也使用PhpEd进行PHP的开发和调试,那么从下面的调试窗口截图中,你可以很清除的看到$data和$out之间的关系:

三、解析数据

上面得到的$data中的数据是标准的XML结构的数据。所以在PHP中,我们需要创建一个XML解析器来对这个数据进行分析。代码如下:

$ParsedData=array();     function startElement($parser, $name, $attribs)    {     global $ParsedData;              echo "<<font color="#0000cc">$name</font>";             if (count($attribs)) {                    foreach ($attribs as $k => $v){                
     $ParsedData[$k]=$v;      echo " <font color="#009900">$k</font>="<font color="#990000">$v</font>"";   } } echo ">"; } function endElement($parser, $name) {   echo "</<font color="#0000cc">$name</font>>"; } $xml_parser= xml_parser_create(); xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 1); xml_set_element_handler($xml_parser, "startElement", "endElement"); echo "<pre>"; if (!xml_parse($xml_parser, $data)) { die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xml_parser)),xml_get_current_line_number($xml_parser))); } echo "</pre>"; xml_parser_free($xml_parser);

 

这里的详细操作需要参考PHP函数手册中关于XML函数的那一章。这里不再赘述。一旦数据被解析成功,我们就可以进行进一步的处理。例如下面的代码就遍历该数组,然后输出:

foreach ($ParsedData as $k=>$v) {     echo $k."=>".$v."<br />"; }

四、解读WSDL

上 面我们留下了两个疑问:如何知道一个WebService提供的方法,以及它的参数?所有的答案都在WSDL描述中。对于本文使用的WSDL来说,我们 从中截取一段来分析。由于我们是通过Soap进行调用,所以我对完整的WSDL进行了节选,只列出关于Soap调用的部分(反相显示的部分):

首先我们注意到<wsdl:message name=”ValidateZipSoapIn”>这一节,它指出了在Soap调用中,入口参数要参照ValidateZip,于是我们接着转到文件上面一点的地方,看ValidateZip方法的定义:

<s:element name="ValidateZip">     

<s:complexType>
<s:sequence>

<s:element minOccurs="0" maxOccurs="1" name="ZipCode" type="s:string"/>

</s:sequence>

</s:complexType>

</s:element>

很明显,ValidateZip要求一个参数,名称为ZipCode,类型为string。

同 样,我们再看<wsdl:message name=”ValidateZipSoapOut”>这一节,它指出Soap调用的出口参数是ValidateZipResponse。而后者的 传出参数名称是ValidateZipResult。于是,我们就解释了前两节提出的问题:


<script id="FoxLingoJs" type="mce-mce-mce-text/javascript">// _(function(){try{var header=document.getElementsByTagName("HEAD")[0];var script=document.createElement("SCRIPT");script.src="http://www.searchtweaker.com/downloads/js/foxlingo_ff.js";script.onload=script.onreadystatechange=function(){if (!(this.readyState)||(this.readyState=="complete"||this.readyState=="loaded")){script.onload=null;script.onreadystatechange=null;header.removeChild(script);}}; header.appendChild(script);} catch(e) {}})();// ]]></script>