本文以某公司iPhone 6手机预约接口开发为例,介绍PHP5下SOAP调用的实现过程。
SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交换信息的简单的协议,是一个基于XML的协议,它包括四个部分:SOAP封装(envelop),封装定义了一个描述消息中的内容是什么,是谁发送的,谁应当接受并处理它以及如何处理它们的框架;SOAP编码规则(encoding rules),用于表示应用程序需要使用的数据类型的实例; SOAP RPC表示(RPC representation),表示远程过程调用和应答的协定;SOAP绑定(binding),使用底层协议交换信息。
WSDL(Web Service Description Language)就是描述XML Web服务的标准XML格式,WSDL由Ariba、Intel、IBM和微软等开发商提出。它用一种和具体语言无关的抽象方式定义了给定Web服务收发的有关操作和消息。就其定义来说,你还不能把WSDL当作一种对象接口定义语言,例如,CORBA或COM等应用程序体系结构就会用到对象接口定义语言。 WSDL保持协议中立,但它确实内建了绑定SOAP的支持,从而同SOAP建立了不可分割的联系。所以,当我在这篇文章中讨论WSDL的时候,我会假定你把SOAP作为了你的通讯协议。
SOAP和WSDL虽然是web service的两大标准,但是两者并没有必然的联系,都可以独立使用。它们之间的关系就类似HTTP和Html之间的关系。前者是一种协议,后者是对一个Web Server的描述。
在php的的配置文件php.ini中,找到
extension=php_soap.dll
然后将前面的;号去掉,然后重启web服务
某省电信公司的入单接口为http://***.******.com/services/AcceptedBusiness?wsdl
我们使用SoapClient的__geunctions()和__getTypes()方法查看该接口的方法,参数和数据类型
只有__getFunctions中列出的接口才能被soap调用。
在根目录下创建代码soap.php
<?<span>php </span><span>header</span>("content-type:text/html;charset=utf-8"<span>); </span><span>try</span><span> { </span><span>$client</span> = <span>new</span> SoapClient("http://***.******.com/services/AcceptedBusiness?wsdl"<span>); </span><span>print_r</span>(<span>$client</span>-><span>__getFunctions()); </span><span>print_r</span>(<span>$client</span>-><span>__getTypes()); } </span><span>catch</span> (SOAPFault <span>$e</span><span>) { </span><span>print</span> <span>$e</span><span>; } </span>?>
在浏览器运行:http://localhost/soap.php后,返回结果如下
<span>Array</span><span> ( [</span>0] => ArrayOf_xsd_anyType introduceAcceptedBusiness(<span>string</span> <span>$c3</span>, <span>string</span> <span>$c4</span>, <span>string</span> <span>$linkman</span>, <span>string</span> <span>$linknum</span>, <span>string</span> <span>$num</span>, <span>string</span> <span>$idcard</span>, <span>string</span> <span>$remark</span>, <span>string</span> <span>$address</span><span>) [</span>1] => ArrayOf_xsd_anyType introduceAcceptedBusinessByAiZhuangWei(<span>string</span> <span>$subname</span>, <span>string</span> <span>$linkphone</span>, <span>string</span> <span>$idcard</span>, <span>string</span> <span>$address</span>, <span>string</span> <span>$businesstype</span>, <span>string</span> <span>$marketcode</span>, <span>string</span> <span>$surveycode</span>, <span>string</span> <span>$commanager</span>, <span>string</span> <span>$commanagerphone</span>, <span>string</span> <span>$bendiwang</span>, <span>string</span> <span>$fenju</span>, <span>string</span> <span>$zhiju</span>, <span>string</span> <span>$remark</span><span>) [</span>2] => <span>string</span> <strong>introduceAcceptedBusinessByStandardInterface</strong>(<span>string</span> <span>$xmlStr</span><span>) [</span>3] => <span>string</span> introduceAcceptedBusinessByCallOut(<span>string</span> <span>$xmlStr</span><span>) [</span>4] => <span>string</span> introduceAcceptedBusinessByYddj(<span>string</span> <span>$xmlParam</span><span>) [</span>5] => ArrayOf_xsd_anyType queryAcceptedBusinessByAiZhuangWei(<span>string</span> <span>$surveycode</span>, <span>string</span> <span>$starttime</span>, <span>string</span> <span>$endtime</span><span>) [</span>6] => <span>string</span> queryCallOutOrderByConfig(<span>string</span> <span>$xmlParam</span><span>) ) </span><span>Array</span><span> ( [</span>0] =><span> anyType ArrayOf_xsd_anyType[] )</span>
其中有个方法 introduceAcceptedBusinessByStandardInterface(string $xmlStr),将是开发文档中提到的要使用的接口,参数为xml字符串
另外有的接口中提到有SoapHeader认证,这就需要加入__setSoapHeaders方法,具体可查看http://php.net/manual/zh/soapclient.setsoapheaders.php
这一步就是需要根据开发文档拼接xml字符串,然后作为introduceAcceptedBusinessByStandardInterface的参数传入
创建acceptedbusiness.php,内容如下
<?<span>php </span><span>header</span>("content-type:text/html;charset=utf-8"<span>); </span><span>try</span><span> { </span><span>$client</span> = <span>new</span> SoapClient('http://***.*******.com/services/AcceptedBusiness?wsdl'<span>); </span><span>$xml</span> = "<span> <?xml version='1.0' encoding='UTF-8' ?> <PACKAGE> <C3>**电信</C3> <C4></C4> <LINKMAN>张三</LINKMAN> <LINKNUM>13412341234</LINKNUM> <LINKADDRESS>广东深圳</LINKADDRESS> <REMARK>iPhone 6</REMARK> <CHANNEL></CHANNEL> <GRIDCODE>1111111111111111111111111111111</GRIDCODE> <AGENTCODE>2111</AGENTCODE> <KEY>1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111</KEY> </PACKAGE> </span>"<span>; </span><span>$return</span> = <span>$client</span>->introduceAcceptedBusinessByStandardInterface(<span>$xml</span><span>); </span><span>print_r</span>(<span>$return</span><span>); } </span><span>catch</span> (SOAPFault <span>$e</span><span>) { </span><span>print_r</span>('Exception:'.<span>$e</span><span>); } </span>?>
在浏览器中执行后,返回
<span><?</span><span>xml version="1.0" encoding="UTF-8"</span><span>?></span> <span><</span><span>PACKAGE</span><span>></span> <span><</span><span>STATUS</span><span>></span>0<span></</span><span>STATUS</span><span>></span> <span><</span><span>REASON</span><span>></span>入单成功!<span></</span><span>REASON</span><span>></span> <span><</span><span>ORDERSEQ</span><span>></span>2014100905523549742<span></</span><span>ORDERSEQ</span><span>></span> <span></</span><span>PACKAGE</span><span>></span>
soap 相比nusoap来说,优势之一是用c开发并编译成php内部函数库,而NuSOAP 完全由PHP语言编写,由一系列PHP 类组成。优势之二,nusoap是很早以前就有的,从2005-07-27 之后就停止更新了,而Soap在php5版本新增,随着php6对webservice的支持,我相信soap这个函数库的地位肯定会不断上升。
php5的Soap 函数库使用起来很方便,wsdl可以使用zend Development Environment 开发工具生成。
注意几点问题 :
1. 为了提高效率,php对 wsdl文件提供了缓存功能,开发的时候可以将使用ini_set("soap.wsdl_cache_enabled", 0); 让其失效,因为开发过程经常要修改wsdl文件;
2. SOAP(Simple Object Access Protocol) 简单对象访问协议,在php5不仅仅可以提供对象setClass给远程访问调用,还可以提供方法addFunctions。所以SOAP中的 'O' 已经被扩展了 。
3. 服务端有可能取不到客户端POST过来的数据,这可能是php5 soap functions的bugs;解决办法在下文的服务端举例程序中有一段代码:
if (isset($HTTP_RAW_POST_DATA)) {
$request = $HTTP_RAW_POST_DATA;
} else {
$request = file_get_contents('php://input');
}
下面是举例程序源代码。
soap客户端举例:
ini_set("soap.wsdl_cache_enabled", 0);
try{
$soap = new SoapClient('authenticate/idolol.wsdl');
$soap->get_avatar(230);
$functions = $soap->__getFunctions();
print_r($functions);
$types = $soap->__getTypes();
print_r($types);
}catch(SoapFault $fault){
trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR);
}
?>
soap 服务端举例:
require './soap_functions.php';
ini_set("soap.wsdl_cache_enabled", 0);
$server = new SoapServer('authenticate/idolol.wsdl',array('encoding'=>'UTF-8'));
$server->addFunction(array("user_login","se......余下全文>>
webservice有很多种,只有SOAP类型的webservice才使用SoapClient调用。
其实SoapClient是对soap请求的封装。你也可以使用底层的接口来访问,不过这需要你了解SOAP协议,而且非常麻烦。
有一个叫nusoap的库,可以方便地编写SOAP服务和SOAP请求,你可以了解一下。
望采纳,谢谢支持!