soap在php中开发有三种,php5 soap,pear soap,nusoap,第一中用c写的,速度较快。后两种用php写的。
安装
在window下开发要打开c:/windows/php.ini修改下。
extension=php_openssl.dll
extension=php_soap.dll
重启apache,看下是否soap支持。
linux下安装,在编译php时候带上enable-soap。
使用
php的soap扩展可以用来提供和使用web services。换句话说,php开发者可以利用这个php扩展来写他们自己的web services,也可以写一些客户端来使用给定的web services。
soap扩展支持以下规范。
* soap 1.1
* soap 1.2
* wsdl 1.1
soap扩展主要用来处理rpc形式的web services。不过,你也可以使用文本形式的wsdl文件配合wsdl模式的服务端和客户端。
这个扩展使用 gnome xml库来处理xml。
扩展中的类
这个扩展实现了6个类。其中有三个高级的类,它们的方法很有用,它们是 soapclient,soapserver和soapfault。另外三个类除了构造器外没有其它别的方法,这三个是低级的类,它们是soapheader,soapparam和soapvar。
soapclient类
这个类用来使用web services。soapclient类可以作为给定web services的客户端。
它有两种操作形式:
* wsdl 模式
* non-wsdl 模式
在wsdl模式中,构造器可以使用wsdl文件名作为参数,并从wsdl中提取服务所使用的信息。
non-wsdl模式中使用参数来传递要使用的信息。这个类有许多可以用来使用服务的有用的方法。其中soapclient::__soapcall()是最重要的。这个方法可以用来调用服务中的某个操作。
soapserver类
这个类可以用来提供web services。与soapclient类似,soapserver也有两种操作模式:wsdl模式和non-wsdl模式。这两种模式的意义跟 soapclient的两种模式一样。在wsdl模式中,服务实现了wsdl提供的接口;在non-wsdl模式中,参数被用来管理服务的行为。
在soapserver类的众多方法中,有三个方法比较重要。它们是
soapserver::setclass(),
soapserver::addfunction(),
soapserver::handle()。
soapserver::setclass()方法设定用来实现web service的类。soapserver::setclass所设定的类中的所有公共方法将成为web services的操作(operation)。
soapserver::addfunction()方法用来添加一个或多个作为web services操作(operation)的函数。
soapserver:: handle()方法指示web service脚本开始处理进入的请求。web service脚本是用php脚本写的一个或多个soapserver对象的实例。尽管你可以有不止一个的soapserver对象,但通常的习惯是一个脚本只拥有一个soapserver实例。在调用soapserver::handle()方法之前,web service脚本会使用设置在soapserver对象实例上的任何信息来处理进入的请求和输出的相应。
soapfault类
这个类从exception类继承而来,可以用来处理错误。soapfault实例可以抛出或获取soap错误的相关信息并按程序员的请求处理。
soapheader类
这个类可以用来描述soap headers。它只是一个只包含构造器方法的数据容器。
soapparam类
soapparam也是一个只包含构造器方法的数据容器。这个方法可以用来描述传递给web services操作的参数。在non-wsdl模式中这是一个很有用的类,可以用来传递所期望格式的参数信息。
soapvar类
soapvar也是一个只包含构造器的低级类,与soapheader和soapparam类相似。这个类可以用来给一个web services操作传递编码参数。这个类对non-wsdl中传递类型信息是非常有用的。
wsdl vs. non-wsdl模式
web services有两种实现模式:契约先行(contract first)模式和代码先行(code first)模式。
契约先行模式使用了一个用xml定义的服务接口的wsdl文件。wsdl文件定义了服务必须实现或客户端必须使用的接口。soapserver和soapclient的wsdl模式就基于这个概念。
在代码先行模式中,首先要先写出实现服务的代码。然后在大多数情况下,代码会产生一个契约,换种说法,一个wsdl。接着客户端在使用服务的时候就可以使用那个wsdl来获得服务的接口。尽管如此,php5的扩展并没有从代码输出一个wsdl的规定,考虑到这种情况,可以在non-wsdl模式下使用 soapserver和soapclient。
soap扩展与hello world
这一节介绍如何使用wsdl模式和non-wsdl模式来实现服务和客户端。相对而言,使用wsdl模式来实现服务和客户端会比较容易,假定已经有一个定义了接口的wsdl文件。因此这一节会先介绍如何使用wsdl模式实现一个web service。
在这个hello world例子的服务中有一个被命名为greet的操作。这个操作有一个字符串形式的名字并返回一个字符串形式的greeting。
wsdl模式服务
下面是wsdl模式的服务所使用的soap扩展api代码:
plain textphp:
function greet($param) {
$retval = ‘hello ‘.$param;
$result = array(’greetreturn’ => $retval);
return $result;
}
$server = new soapserver(’hello.wsdl’);
$server->addfunction(’greet’);
$server->handle();
?>
在这个服务的实现过程中,函数实现了wsdl所定义的服务操作greet,greet操作有一个wsdl指定的参数,按照greet操作的语义,这个参数是一个用户的名字。最后handle调用了触发处理请求的服务对象。
wsdl模式客户端
客户端代码如下
plain textphp:
try {
$client = new soapclient(’hello.wsdl’);
$result = $client->__soapcall(’greet’, array(array(’name’ => ‘sam’)));
printf(”result = %s/n”, $result->greetreturn);
} catch (exception $e) {
printf(”message = %s/n”,$e->__tostring());
}
?>
客户端代码中,首先创建一个使用wsdl文件作参数的soapclient实例。接着__soapcall()调用作为参数传入它的操作,也就是greet和传入操作的参数。
请求和响应
当你将上述的php脚本放在你web服务器目录下的文档中,并利用web浏览器或在php解析器的命令行调用脚本,客户端发送一个soap请求到服务端脚本,服务端将向客户端发送一个soap响应来响应客户端的请求。
上面的soap消息都是利用wsdl模式的服务端和客户端来获取的。也可以利用non-wsdl模式的服务端和客户端来产生与上面相同的soap消息。但是,php代码必须有一点改变。下一节会说明如何使用non-wsdl模式。
non-wsdl模式服务端
plain textphp:
function greet($param) {
$retval = ‘hello ‘.$param;
return new soapparam($retval, ‘greetreturn’);
}
$server = new soapserver(null, array(’uri’ => ‘http://wso2.org/wsf/php/helloservice’));
$server->addfunction(’greet’);
$server->handle();
?>
在non -wsdl模式中,想wsdl模式一样首先实现greet函数的功能,但是函数实现的方式跟wsdl模式稍稍有所不同。在non-wsdl模式中,我们必须返回一个soapparam对象作为响应,而不是一个数组。创建服务时,第一个参数设为null,说明没有提供wsdl;接着传递一个选项作为参数,这个选项参数是服务的uri。最后像wsdl模式一样调用剩下的方法。
non-wsdl模式客户端
plain textphp:
try {
$client = new soapclient(null,
array(’location’ => ‘http://localhost/hello/hello_service_nonwsdl.php’,
‘uri’ => ‘http://wso2.org/wsf/php/helloservice’));
$result = $client->__soapcall(’greet’, array(new soapparam(’sam’, ‘name’))); printf(”result = %s/n”, $result);
} catch (exception $e) {
printf(”message = %s/n”,$e->__tostring());
}
?>
在non-wshdl模式中,因为p没有使用wsdl,传递了一个包含服务所在位置和服务uri的参数数组作为参数。然后象wsdl模式中一样调用__soapcall()方法,但是使用了soapparam类用指定格式打包参数。返回的结果将获取greet中的响应。
结论
这篇文章介绍了soap扩展,可以在php中通过它来提供和使用web services。php扩展的强项是它的简单和快速。使用c写的soap扩展来运行服务端和客户端是非常简单的。虽然soap扩展在处理一些简单的 web services时很有用,但是当用它来处理所有的web services时就表现出它的局限性。 wso wsf/php就是为了弥补php扩展的缺陷而开发的,它是开源的,可以实现soap类似的功能并且支持mtom,ws-addressing,ws- security和ws-relaiablemessaging。wso2 wsf/php 支持与soap扩展类似的api。