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 相关文章推荐
?繁体转换的class
Oct 09 PHP
php开发环境配置记录
Jan 14 PHP
基于PHP的cURL快速入门教程 (小偷采集程序)
Jun 02 PHP
CodeIgniter框架过滤HTML危险代码
Jun 12 PHP
CodeIgniter中实现泛域名解析
Jul 19 PHP
PHP 实现类似js中alert() 提示框
Mar 18 PHP
PHP合并discuz用户脚本的方法
Aug 04 PHP
php实现scws中文分词搜索的方法
Dec 25 PHP
使用phpQuery获取数组的实例
Mar 13 PHP
php之header的不同用法总结(实例讲解)
Nov 28 PHP
laravel ORM关联关系中的 with和whereHas用法
Oct 16 PHP
PHP常量DIRECTORY_SEPARATOR原理及用法解析
Nov 10 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
Admin generator, filters and I18n
2011/10/06 PHP
PHP图片上传代码
2013/11/04 PHP
php微信公众号开发(4)php实现自定义关键字回复
2016/12/15 PHP
PHP面向对象程序设计OOP继承用法入门示例
2016/12/27 PHP
PHP面向对象之领域模型+数据映射器实例(分析)
2017/06/21 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
js cookies 常见网页木马挂马代码 24小时只加载一次
2009/04/13 Javascript
Javascript学习笔记9 prototype封装继承
2010/01/11 Javascript
javascript页面动态显示时间变化示例代码
2013/12/18 Javascript
Javascript实现登录记住用户名和密码功能
2017/03/22 Javascript
JS表单提交验证、input(type=number) 去三角 刷新验证码
2017/06/21 Javascript
vue的基本用法与常见指令
2017/08/15 Javascript
bootstrap表格内容过长时用省略号表示的解决方法
2017/11/21 Javascript
vue使用ajax获取后台数据进行显示的示例
2018/08/09 Javascript
新手入门带你学习JavaScript引擎运行原理
2019/06/24 Javascript
python三元运算符实现方法
2013/12/17 Python
Python编程使用*解包和itertools.product()求笛卡尔积的方法
2017/12/18 Python
Python操作MySQL数据库的两种方式实例分析【pymysql和pandas】
2019/03/18 Python
Python3.5文件读与写操作经典实例详解
2019/05/01 Python
Python使用Opencv实现图像特征检测与匹配的方法
2019/10/30 Python
Python全局锁中如何合理运用多线程(多进程)
2019/11/06 Python
关于win10在tensorflow的安装及在pycharm中运行步骤详解
2020/03/16 Python
Keras-多输入多输出实例(多任务)
2020/06/22 Python
python 基于opencv 绘制图像轮廓
2020/12/11 Python
前端面试必备之html5的新特性
2017/09/05 HTML / CSS
西班牙美妆电商:Perfume’s Club(有中文站)
2018/08/08 全球购物
房地产公司见习自我鉴定
2014/04/28 职场文书
彩妆大赛策划方案
2014/05/13 职场文书
新党章的学习心得体会
2014/11/07 职场文书
谢师宴答谢词
2015/01/05 职场文书
综合办公室主任岗位职责
2015/04/01 职场文书
2016暑期社会实践心得体会范文
2016/01/14 职场文书
php png失真的原因及解决办法
2021/11/17 PHP
面试中canvas绘制图片模糊图片问题处理
2022/03/13 Javascript
Oracle查看表空间使用率以及爆满解决方案详解
2022/07/23 Oracle
volatile保证可见性及重排序方法
2022/08/05 Java/Android