PHP使用SOAP扩展实现WebService的方法


Posted in PHP onApril 01, 2016

本文实例讲述了PHP使用SOAP扩展实现WebService的方法。分享给大家供大家参考,具体如下:

最近在一个PHP项目中对接外部接口涉及到WebService,搜索引擎上相关文章不是很多,找到的大都是引用一个号称很强大的开源软件NuSOAP(下载地址:http://sourceforge.net/projects/nusoap/),即一些类。文章写描述的环境是PHP 4.3,现在都流行PHP 5.2或PHP 5.3了。先拿来试试,运行出错,原来NuSOAP提供的soapclient类与PHP 5中新增了内置的SOAP扩展的SoapClient类冲突了。

虽然NuSOAP号称可以用于所有的PHP 环境,不受服务器安全设置的影响。但需要引用一大堆类文件,还是觉得用PHP 5中新增了内置的SOAP扩展好一些,能实现实用就好。先了解一下SOAP:

一、SOAP和XML-PRC比较

在Web服务发展的初期,XML格式化消息的第一个主要用途是,应用于XML-RPC协议,其中RPC代表远程过程调用。在XML远程过程调用(XML-RPC)中,客户端发送一条特定消息,该消息中必须包括名称、运行服务的程序以及输入参数。

XML-RPC只能使用有限的数据类型种类和一些简单的数据结构。人们认为这个协议还不够强大,于是就出现了SOAP——其最初的定义是简单对象访问协议。之后,大家逐渐意识到SOAP其实并不简单,而且也不需要必须使用面向对象语言,所以,现在人们只是沿用SOAP这个名称而已。

XML-RPC只有简单的数据类型集,取而代之,SOAP是通过利用XML Schema的不断发展来定义数据类型的。同时,SOAP也能够利用XML 命名空间,这是XML-RPC所不需要的。如此一来,SOAP消息的开头部分就可以是任何类型的XML命名空间声明,其代价是在系统之间增加了更多的复杂性和不兼容性。

随着计算机行业的觉醒,人们发现了基于XML的Web服务的商业潜力,于是,各家公司开始不断地发掘想法、观点、论据以及标准化尝试。W3C曾经设法以“Web服务活动”的名义来组织成果展,其中也包括实际做出SOAP的XML协议工作组(XML Protocol Working Group)。与Web服务有关的标准化成果(从某种程度上说与SOAP相关或者依赖于SOAP)的数量已经倍增了到了令人惊讶的程度。

最初,SOAP是作为XML-RPC的扩展而发展起来的,它主要强调的是,通过从WSDL文件中所获得的方法和变量名来进行远程过程调用。现在,通过不断进步,人们发现了更多的使用SOAP的方式,而不仅仅是采用“文件”方式——基本上是使用一个SOAP信封来传送XML格式化文件。无论如何,要掌握SOAP,了解WSDL所扮演的角色是最根本的。

二、SOAP数据包结构解析

SOAP的消息被称为一个SOAP Envelope,包括SOAP Header和SOAP Body。其中,SOAP Header可以方便的插入各种其它消息来扩充Web Service的功能,比如Security(采用证书访问Web Service),SOAP Body则是具体的消息正文,也就是Marshall后的信息。

SOAP调用的时候,也就是向一个URL(比如 http://api.google.com/search/beta2 )发送HTTP Post报文(根据SOAP规范,HTTP Get报文也可被支持),调用方法的名字在HTTP Request Header SOAP-Action中给出,接下来就是SOAP Envelope了。服务端接到请求,执行计算,将返回结果Marshall成XML,用HTTP返回给客户端。

三、SOAP简单示例

SOAP开发一般有三种方式选择:

1)、PEAR自带的SOAP扩展;
2)、PHP自带的SOAP扩展;
3)、NuSOAP(纯PHP) 。

PHP 5中新增了内置的SOAP扩展,作为PHP的一部分提供的,因此不需要下载、安装和管理单独的包。这是第一个用C而不是PHP为PHP编写的SOAP实现,因此作者声称它的速度要快得多。相关文档包含在PHP手册的Function Reference部分(php_soap.dll)。

一个访问.NET WEB服务的客户端例子:

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

四、实例

1)、用PHP建立SOAP服务

建立soap_server.php(虚拟路径为:http://localhost/php/soap/soap_server.php)

< ? php
/**
* A simple math utility class
*/
class math{
  /**
  * Add two integers together
  *
  * @param integer $a The first integer of the addition
  * @param integer $b The second integer of the addition
  * @return integer The sum of the provided integers
  */
  public function add($a, $b){
    return $a + $b;
  }
  /**
  * Subtract two integers from each other
  *
  * @param integer $a The first integer of the subtraction
  * @param integer $b The second integer of the subtraction
  * @return integer The difference of the provided integers
  */
  public function sub($a, $b){
    return $a - $b;
  }
  /**
  * Div two integers from each other
  *
  * @param integer $a The first integer of the subtraction
  * @param integer $b The second integer of the subtraction
  * @return double The difference of the provided integers
  */
  public function div($a, $b){
    if($b == 0){
      throw new SoapFault(-1, "Cannot divide by zero!");
    }
    return $a / $b;
  }
}
$server = new SoapServer('math.wsdl', array('soap_version'=>SOAP_1_2));
$server->setClass("math");
$server->handle(); 
?>

注:

a)、math类是即将公开的webservice;
b)、$server->setClass,不是$server->addClass。
2)、用PHP客户端访问刚建立SOAP服务

< ? php
// $client = new SoapClient('http://localhost/php/soap/math.wsdl');
$client = new SoapClient("http://localhost/php/soap/soap_server.php?WSDL");
try{
  $result = $client->div(8, 2); // will cause a Soap Fault if divide by zero
  print "The answer is: $result";
}catch(SoapFault $e){
  print "Sorry an error was caught executing your request: {$e->getMessage()}";
}
?>

本质上,http://localhost/php/soap/soap_server.php?WSDL就是要访问到注释行所指的wsdl描述文件,所以这个WSDL文件必须事先生成。而对于其他语言如Java则可以动态生成。对于PHP自带的SOAP扩展要求这个WSDL文件必须事先生成好。

可以用ZendStudio生成静态的WSDL文件,此时用到math类的phpdoc作为生成WSDL的元数据。用ZendStudio生成wsdl文件时,必须正确说明Web服务目标地址,片断如下:

...
  <service name="mathService">
    <port binding="typens:mathBinding" name="mathPort">
      <soap:address location="http://localhost/php/soap/soap_server.php"></soap:address>
    </port>
  </service>
...

注:调用PHP Webserver的方法必须传入命名参数。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP5中虚函数的实现方法分享
Apr 20 PHP
php性能优化分析工具XDebug 大型网站调试工具
May 22 PHP
PHP中文件读、写、删的操作(PHP中对文件和目录操作)
Mar 06 PHP
通过5个php实例细致说明传值与传引用的区别
Aug 08 PHP
简单的方法让你的后台登录更加安全(php中加session验证)
Aug 22 PHP
php获取远程文件的内容和大小
Nov 03 PHP
Yii rules常用规则示例
Mar 15 PHP
smarty自定义函数用法示例
May 20 PHP
PHP array_key_exists检查键名或索引是否存在于数组中的实现方法
Jun 13 PHP
Yii2 队列 shmilyzxt/yii2-queue 简单概述
Aug 02 PHP
Laravel中七个非常有用但很少人知道的Carbon方法
Sep 21 PHP
PHP内存溢出优化代码详解
Feb 26 PHP
PHP全局变量与超级全局变量区别分析
Apr 01 #PHP
PHP计算数组中值的和与乘积的方法(array_sum与array_product函数)
Apr 01 #PHP
PHP采用超长(超大)数字运算防止数字以科学计数法显示的方法
Apr 01 #PHP
Zend Studio使用技巧两则
Apr 01 #PHP
PHP数学运算与数据处理实例分析
Apr 01 #PHP
PHP数学运算函数大汇总(经典值得收藏)
Apr 01 #PHP
PHP操作FTP类 (上传、下载、移动、创建等)
Mar 31 #PHP
You might like
破解.net程序(dll文件)编译和反编译方法
2013/01/31 PHP
让CodeIgniter数据库缓存自动过期的处理的方法
2014/06/12 PHP
php中rename函数用法分析
2014/11/15 PHP
php内存缓存实现方法
2015/01/24 PHP
浅谈使用PHP开发微信支付的流程
2015/10/04 PHP
关于PHP 如何用 curl 读取 HTTP chunked 数据
2016/02/26 PHP
PHP调用存储过程返回值不一致问题的解决方法分析
2016/04/26 PHP
laravel 5.5 关闭token的3种实现方式
2019/10/24 PHP
Js,alert出现乱码问题的解决方法
2013/06/19 Javascript
使用Js让Html中特殊字符不被转义
2013/11/05 Javascript
JavaScript表单通过正则表达式验证电话号码
2014/03/14 Javascript
使用原生js封装webapp滑动效果(惯性滑动、滑动回弹)
2014/05/06 Javascript
extjs每个组件要设置唯一的ID否则会出错
2014/06/15 Javascript
AngularJS快速入门
2015/04/02 Javascript
jquery背景跟随鼠标滑动导航
2015/11/20 Javascript
详解Jquery实现ready和bind事件
2016/04/14 Javascript
jQuery实现图片轮播效果代码
2016/09/27 Javascript
canvas实现手机端用来上传用户头像的代码
2016/10/20 Javascript
Bootstrap CSS组件之输入框组
2016/12/17 Javascript
vue 封装面包屑组件教程
2020/11/16 Javascript
[00:38]TI珍贵瞬间系列(二):笑
2020/08/26 DOTA
Python爬虫实现全国失信被执行人名单查询功能示例
2018/05/03 Python
详解Python中的四种队列
2018/05/21 Python
Python设计模式之策略模式实例详解
2019/01/21 Python
在pandas中遍历DataFrame行的实现方法
2019/10/23 Python
美国演唱会和体育门票购买网站:Ticketnetwork
2018/10/19 全球购物
Mountain Warehouse德国官网:英国户外零售商
2019/08/11 全球购物
Envie de Fraise意大利:法国网上推出的孕妇装品牌
2020/10/18 全球购物
机电一体化专业应届本科生求职信
2013/09/27 职场文书
卫校护理专业毕业生求职信
2013/11/26 职场文书
幼儿园教师节活动方案
2014/02/02 职场文书
护士试用期自我鉴定
2014/02/08 职场文书
破坏寝室公物检讨书
2014/11/17 职场文书
结婚保证书(卖身契)
2015/02/26 职场文书
五星级酒店前台接待岗位职责
2015/04/02 职场文书
2015年个人审计工作总结
2015/04/07 职场文书