时间:2021-07-01 10:21:17 帮助过:5人阅读
继续昨天的学习。今天主要是关于NuSOAP
Section 2. SOAP NuSOAP介绍: NuSOAP是一组开源的,用来通过HTTP收发SOAP消息的PHP类,由NuSphere Corporation ( http://www.nusphere.com/
) 开发。NuSOAP的一个优势是他不是一个扩展程序,而是纯粹用PHP代码写的,所以适用范围比较广。
结构:
安装配置: 从 http://dietrich.ganx4.com/nusoap/ 下载,从zip文件中解出nusoap.php文件放到include目录,在你的脚本前面加上
include('nusoap.php');
就搞定了。
范例: 下面是一个简单的SOAP client程序: soap_client.php 执行
//simple client
require('nusoap.php');
//要发送的变量
$myString="world";
//parameters must be passed as an array
//变量必须要转换成数组的形式
$parameters=array($myString);
//创建一个soapclient对象,参数是server的URL
$s=new soapclient('http://www.douzi.org/me/php_ws/soap_server.php');
//调用远程方法,返回值存放在$result
//返回值为PHP的变量类型,如string, integer, array
$result=$s->call('echoString', $parameters);
//错误检测
if (!$err=$s->getError()) {
echo 'Result: '.$result; //success
} else {
echo 'Error: '.$err;
}
//调试,以下是SOAP请求(request)和回应(response)的报文,包括HTTP头
echo "<xmp>".$s->request."</xmp>";
echo "<xmp>".$s->response."</xmp>";
?>
//simple server
require('nusoap.php');
//创建一个新的soap_server对象,并注册允许远程调用的方法
$s=new soap_server;
$s->register('echoString');
$s->register('echoArray');
/*
[文章中说: 缺少了注册这一步,任何PHP函数都将可以进行远程调用,这将是一个极大的安全隐患。但是我尝试过注册是必须的。而且只有将结果return的函数才能直接声明为远程方法,比如echo()就不行,而strtolower()就可以。]
*/
function echoString($inputString) {
//类性检查
if(is_string($inputString)) {
return "Hello, ".$inputString;
} else {
//soap_fault类用于产生错误信息
return new soap_fault('client', '', 'The parameter to this service must be a string.');
//soap_fault(faultcode, faultactor, faultstring, faultdetail);
//上面是错误处理类的构造函数的格式
//faultcode 必须值。可以设置为client或server,来表明错误发生在哪一端。
//faultactor 在NuSOAP中尚未实现。
//faultstring 错误信息。
//faultdetail 详细错误信息。你可以使用XML标记。
//除了构造函数外,soap_fault类还有一个serialize()方法
//它将错误信息序列化,然后返回一个完整的SOAP报文,范例:
/*
$fault = new soap_fault('client', '', 'The inputString parameter must not be empty');
echo $fault->serialize();
*/
}
}
//演示数组类型的使用
function echoArray($inputString) {
return $inputString[0]."+".$inputString[1];
}
//最后一步是把所有的收到的post数据都传递给SOAP server的service方法。它将处理请求,并调用相应的函数。
$s->service($HTTP_RAW_POST_DATA);
?>
string1
string2
123 Freezing Lane
Nome
Alaska
12345
1234567890
0987654321
//soapval: general compound types samples
include('nusoap.php');
$address=array(
'street'=>'123 Freezing Lane',
'city'=>'Nome',
'state'=>'Alaska',
'zip'=>12345,
'phonenumbers'=>array('home'=>'1234567890', 'mobile'=>'0987654321')
);
$s=new soapval('myAddress', 'address', $address, '', 'http://myNamespace.com');
print "<xmp>".$s->serialize()."</xmp>";
?>
//wsdl的一个简单演示文件
include('nusoap.php');
//SOAP源为一个提供明星生卒年月的service
//首先我们创建一个soapclient对象,把WSDL文件的URL传递给构造函数,
//之后还要使用第二个参数以便使client知道我们传递过来的是WSDL,而不是SOAP endpoint。
$s=new soapclient('http://www.abundanttech.com/webservices/deadoralive/deadoralive.wsdl', 'wsdl');
//生成proxy类
$p=$s->getProxy();
//调用远程函数
$sq=$p->getTodaysBirthdays();
if (!$err=$p->getError()) {
print_r($sq);
} else {
print "ERROR: $err";
}
print 'REQUEST:<xmp>'.$p->request.'</xmp>';
print 'RESPONSE:<xmp>'.str_replace('><', ">\n<", $p->response).'</xmp>';
?>
这是最后一节,感觉PHP还是很适合做client的。这节主要是关于XML-RPC的。
我原来曾经有一篇XML-RPC学习笔记,内容和这个很类似。
XML-RPC仅支持有限的几种数据类型。下面是和PHP数据类型的的对应关系:
我们使用的XML-RPC工具包是Useful, Inc.的Edd Dumbill制作的,下载网址 http://phpxmlrpc.sourceforge.net/ ,其中完整包括client和server的XML-RPC实现。
客户端和服务器端分别由 xmlrpc_client 类和 xmlrpc_server 类实现,主要用于接收和发送XML-RPC报文。xmlrpcval 类用于将PHP变量编码为XML-RPC等价数据类型和向远程方法传递参数。相反的过程使用 xmlrpc_decode() 函数。XML-RPC报文使用 xmlrpcmsg 类通过传递给它一个参数表来创建。
xmlrpc_client 类发送使用 xmlrpcmsg 类创建的XML-RPC报文,在服务器端, xmlrpc_server 类解析这些收到的报文为 xmlrpcmsg 对象。然后这个对象被作为一个单独参数传递给用户函数。该函数必须返回一个 xmlrpcresp 对象, xmlrpc_server 类将其用于序列化并返回给客户端。这个基本的体系结构如下图所示。
在 http://phpxmlrpc.sourceforge.net/ 下载,解包,然后将 xmlrpc.inc 和 xmlrpcs.inc 放置到你的包含路径即可。
客户端程序首部只要加入下面的包含语句:
include('xmlrpc.inc');
服务器端程序首部要加入下面的包含语句:
include('xmlrpc.inc');
include('xmlrpcs.inc'); //服务器端代码
XML-RPC client: xmlrpc_client.php 执行
//xmlrpc_client.php
//XML-RPC客户端演示程序
require('xmlrpc.inc');
//创建client对象, 三个参数依次为 path, hostname, port
$s=new xmlrpc_client('/xmlrpc/xmlrpc_server.php', 'www.windix.local', 80);
//create xmlrpcval object, which allows the encoding of our variable
//创建xmlrpcval对象,将我们的PHP变量编码为XML-RPC需要的XML形式
$inputString=new xmlrpcval('world', 'string');
//create an array of parameters
//尽管我们只有一个参数,但仍然要转换成数组的形式,因为xmlrpcmsg的第二个参数是一个参数表
$parameters=array($inputString);
//create the message object
//创建XML-RPC报文,参数分别为 远程方法名 和 参数表
$msg=new xmlrpcmsg('echoString', $parameters);
//send the message, get the response
//发送报文,返回值$rsp为一个xmlrpcresp对象,它包含以下三个方法:
//faultCode() 出错代码,如果成功将返回0
//faultString() 出错信息
//value() 返回值,以xmlrpcval对象形式存在,PHP使用前需要进行解码
$rsp=$s->send($msg);
//check for errors
if($rsp->faultcode()==0) {
//decode the response to a PHP type
//xmlrpc_decode()函数用于将xmlrpcval对象解码
$response=xmlrpc_decode($rsp->value());
//print results
print '
'';
XML-RPC server: xmlrpc_server.php
//xmlrpc_server.php
//XML-RPC服务器端演示程序
require('xmlrpc.inc');
require('xmlrpcs.inc');
//service that echoes a string
//我们用于处理远程调用的自定义函数
//注意,该函数必须且只能有一个类型为xmlrpcmsg对象的参数
function echoString($msg) {
//decode parameters into navtive types
//首先使用xmlrpc_decode函数进行解码
$inputString=xmlrpc_decode(array_shift($msg->params));
//check for input parameter validity
//检查数据类型是否正确
if(is_string($inputString)) {
return new xmlrpcresp( new xmlrpcval('Hello, '.$inputString, 'string') );
} else { //or return a fault
return new xmlrpcresp(0, $xmlrpcerruser+1, "Parameter type ".gettype($inputString)." mismatched expected type.");
}
}
//instantiate the server object and register our functions
//初始化server对象,并注册我们的函数
//下面这个数组称为"dispatch map",其中以输出函数名为主键的项又是一个数组
//包含以下三个成员:
// function 实际调用的函数名,在这里我们的函数名也是echoString,同服务名一样
// signature 可选。输入和输出参数的类型,最后一个是输出参数,前面的都是输入参数
// docstring 可选。包含你的服务的文档,甚至可以有HTML内容。
//xmlrpc_server还包含第二个可选初始化参数,如果设置为0,则服务不会立刻处理请求
//需要使用server的service()方法进程才能被执行
$s=new xmlrpc_server(array(
'echoString' => array(
'function' => 'echoString',
'signature' => array( array('string','string') ),
'docstring' => 'This service echoes Hello+input stirng.'
)
));
?>