php soap 扩展
soap 的全称为简单对象访问协议 (simple object access protocol)。它是一种基于 xml 的,可扩展的通信协议。soap 提供了一种标准,使得运行在不同平台上并使用不同的编程语言编写的应用程序可以互相进行通信。soap 的可扩展性和平台无关性使得它被广泛用作 web 服务的通信协议。
由于 java 语言提供了对 soap 的良好支持,通常基于 web 服务的应用程序使用 java 语言编写。对于广大的 php 程序员来说,可能会有一点小小的不满 – php 的较早版本根本没有对 soap 的直接支持,只能通过 pear(the php extension and application repository) 中的 soap 库或者第三方产品 nusoap 来开发 web 服务。不过最近的版本已经改变了这一状况。自 php 5 开始新增了内置的 soap 扩展 (ext/soap),从此我们不需要下载额外的扩展库或是代码包来开发基于 soap 的应用程序了。接下来让我们来看看 soap 扩展中都有哪些内容。
php 5 中的 soap 扩展 (ext/soap)php 5 最早发布的版本 5.0.0 中就已经提供了 soap 扩展,不过当时的 php 手册中声明这个扩展是试验性 (experimental) 的。实际上当时的版本已经实现了比较完善的功能,也没有必要为此而担心。目前这个扩展还在不断地完善,早期版本中的大部分 bug 都已经得到了修正,目前最新的版本 (5.3.0) 中已经提供了比较完整的对 soap 的支持,而且我们有理由相信,以后的版本还会更好。
soap 扩展库结构
ext/soap 中包括六个预定义的类,通过这些类,我们可以创建 web 服务端 (soapserver 类 ),客户端 (soapclient 类 ),处理 soap 请求和应答 (soapheader, soapparam, soapvar 类 ),诊断错误 (soapfault 类 )。这些类之间的联系如图 1 所示:
图 1. soap 扩展的结构
soap 服务类 soapserver
soapserver 类用来开发 web 服务端应用程序。这个类中包含创建,设置和操纵 web 服务的函数。有两种方式可以向 web 服务中添加操作 (operation)。一种方式是直接添加已定义的函数,另一种方式是添加已定义好的类,从而将该类的公有成员函数添加到 web 服务中。
另一个需要说明的特性是,php 支持两种 web 服务的模式:wsdl 模式和 non-wsdl 模式,为了便于理解,我们首先从 web 服务的两种实现模式开始说起。
php 中 web 服务的两种模式:wsdl 模式和 non-wsdl 模式
对于 web 服务来说,主要有两种实现模式 – 契约先行 (contract first) 模式和代码先行 (code fist) 模式。
契约先行模式的实现中,首要工作是定义针对这个 web 服务的借口的 wsdl(web services description language,web 服务描述语言 ) 文件。wsdl 文件中描述了 web 服务的位置,可提供的操作集,以及其他一些属性。wsdl 文件也就是 web 服务的“契约”。“契约”订立之后,再据此进行服务器端和客户端的应用程序开发。这种模式对应上节所说的 wsdl 模式。我们后文中介绍的例子就是使用这一模式实现的。
与契约先行模式不同,代码先行模式中,第一步工作是实现 web 服务端,然后根据服务端的实现,用某种方法(自动生成或手工编写)生成 wsdl 文件。但是由于 php 本身并没有提供从 web 服务实现代码中生成 wsdl 文件的方法,因此就要以 non-wsdl 模式连接服务端,即不通过 wsdl 文件创建 soapserver 和 soapclient 示例,而是直接向构造函数传递必要的参数。当然,代码先行模式也有其他的解决方法,一些集成的 php 开发工具(如 zend studio)就提供了根据 web 服务实现代码生成 wsdl 文件的功能。
soap 客户端类 soapclient
soap 客户端类 soapclient 用于开发 web 服务的客户端程序。可用的成员函数主要有创建客户端实例,调用可用操作,查询可用操作和数据类型等。除此之外还包括了可用于程序调试的函数 – 获取上次请求和应答的 soap 数据。
soap 参数类 soapheader, soapparam, soapvar
soapparam 和 soapvar 主要用来封装用于放入 soap 请求中的数据,他们主要在 non-wsdl 模式下使用。事实上,在 wsdl 模式下,soap 请求的参数可以通过数组方式包装,soap 扩展会根据 wsdl 文件将这个数组转化成为 soap 请求中的数据部分,所以并不需要这两个类。而在 non-wsdl 模式下,由于没有提供 wsdl 文件,所以必须通过这两个类进行包装。
soapheader 类用来构造 soap 头,soap 头可以对 soap 的能力进行必要的扩展。soap 头的一个主要作用就是用于简单的身份认证,后面会有例子说明这一点。
soap 异常类 soapfault
这个类从 php 的 exception 类继承而来,可以用来实现 soap 中的异常处理机制,由 soap 服务端抛出。soap 客户端可以接收该类的实例,用于获取有用的调试信息。
安装 soap 扩展为了使用 soap 扩展,我们就需要在 web 服务器上安装它。这里有几个因素需要考虑。
安装的前置条件:在官方的使用手册中可以找到,ext/soap 扩展使用了 gnome xml 库,因此在安装 soap 扩展之前需要安装这个库(需要 2.5.4 以上版本)。 php 是否已安装: 如果你想在安装 php 的同时加入 soap 扩展,那再简单不过了。如果是下载 php 源代码自己编译安装的情况,则只需要在编译时的 configure 命令中添加选项 --enable-soap 即可。如果是直接使用二进制文件安装(通常只用于 windows 平台),安装包中则已经包括了这一扩展,不需要额外安装。 而如果需要在已经安装好的 php 上添加 soap 扩展,需要做的工作就要多一些。在编译 soap 扩展的源代码之前需要使用 phpize 命令设置编译环境,然后再使用 configure 命令,之后编译并安装 soap 扩展。 编译安装 soap 扩展之后,我们还需要修改 php 的配置文件,以便 soap 扩展可以正确的被 php 加载。对于 linux 平台来说,需要在 php.ini 中加入如下代码:
extension = php_soap.so [/pre]
而对于 windows 平台,需要加入的代码为:
extension = php_soap.dll [/pre]
除此之外,可能还需要设置扩展库的位置,这一信息在 php.ini 的 extension_dir 域中保存,例如:
extension_dir = /usr/local/php/lib/[/pre]
上面的工作完成之后,还需要注意的是 soap 扩展在配置文件中有独立的代码段:
清单 1.php.ini 中 soap 扩展的设置
soap]; enables or disables wsdl caching feature.soap.wsdl_cache_enabled=1; sets the directory name where soap extension will put cache files.soap.wsdl_cache_dir=c:/xampp/tmp; (time to live) sets the number of second while cached file will be used; instead of original one.soap.wsdl_cache_ttl=86400 [/pre]
其中的三项设置主要是用来指定 php 处理 wsdl 文件时使用缓存的行为。这三项设置分别说明是否启用缓存、缓存文件的路径、缓存的生存时间。启用缓存会加快 php 处理 wsdl 文件的速度,但最好在调试代码时关闭缓存,以避免一些因缓存行为而出现的问题。
