全部博文(315)
分类:
2008-03-04 17:25:51
一、介绍
Zend Framework在Zend_XmlRpc_Client包中提供支持了强远端XML-RPC服务作为一个客户端。其主要特性包括:PHP和XML-RPC之间自动类型转换,一个服务器代理对象和存储服务器内部的容器。
二、方法调用
Zend_XmlRpc_Client的构造器接受远端XML-RPC服务器端点的URL作为它的第一个参数。
使用XML-PRC调用远端方法,实例化它可使用call()实例方法。下面的一个例子是使用ZF网站的XML-RPC服务器。
require_once 'Zend/XmlRpc/Client.php';
$client = new Zend_XmlRpc_Client('');
echo $client->call('test.sayHello');
// hello
从远端方法调用的XML-RPC返回值将自动的转成PHP本地类型。在上面的例子中,返回一个php字符串。
Call()方法的第一个参数接受远端方法的名字来调用。远端方法可以有第二个参数并能由一个数组的方式传送给它
require_once'Zend/XmlRpc/Client.php';$client= newZend_XmlRpc_Client('');$arg1=1.1;$arg2='foo';$result=$client->call('test.sayHello', array($arg1,$arg2));// $result is a native PHP type
如果远端方法不需要参数,可选参数要么被丢弃,要么传给一个空的数组。传给远端方法的数组参数可以包含php类型,Zend_XmlRpc_Value对象或是一个混合体。
Call()方法会自动转换XML-RPC响应为php类型。通过调用getLastResponse方法可以获得Zend_XmlRpc_Response对象的返回值。
三、类型和转换
传给Call()方法的php变量可以被自动检测并且转换成XML-RPC的类型
Table 42.1. PHP and XML-RPC Type Conversions
|
PHP Native Type |
XML-RPC Type |
|
integer |
int |
|
double |
double |
|
boolean |
boolean |
|
string |
string |
|
array |
array |
|
associative array |
struct |
|
object |
array |
Zend_XmlRpc_Value对象作为参数
可以使用Zend_XmlRpc_Value来指定一个精确的XML-RPC类型,原因如下:
1、 确认正确的参数类型(比如从数据库传来的字符串,但需要的是整数)
2、 当需要base64或是ISO8601的时间格式类型(PHP不存在的类型)
3、 自动转换也许会失败。
有两个办法来创建一个Zend_XmlRpc_Client对象:直接实例化该子类。或使用静态构造Zend_XmlRpc_Value::getXmlRpcValue()
Table 42.2. Zend_XmlRpc_Value Objects for XML-RPC Types
|
XML-RPC Type |
Zend_XmlRpc_Value Constant |
Zend_XmlRpc_Value Object |
|
int |
Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER |
Zend_XmlRpc_Value_Integer |
|
double |
Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE |
Zend_XmlRpc_Value_Double |
|
boolean |
Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN |
Zend_XmlRpc_Value_Boolean |
|
string |
Zend_XmlRpc_Value::XMLRPC_TYPE_STRING |
Zend_XmlRpc_Value_String |
|
base64 |
Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64 |
Zend_XmlRpc_Value_Base64 |
|
dateTime.iso8601 |
Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME |
Zend_XmlRpc_Value_DateTime |
|
array |
Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY |
Zend_XmlRpc_Value_Array |
|
struct |
Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT |
Zend_XmlRpc_Value_Struct |
四、服务器代理对象
用XML-RPC客户端调用远端方法的另一个办法就是使用服务器代理。这是一个PHP对象,它代理一个远端XML-RPC的命名空间,并使之工作尽可能的类似一个php对象
如要实例化一个服务器代理,需调用Zend_XmlRpc_Client方法的getProxy()实例。这将返回一个Zend_XmlRpc_Client_ServerProxy的实例.该实例的任何方法调用都将传给远端服务器。
require_once'Zend/XmlRpc/Client.php';$client= newZend_XmlRpc_Client('');$server=$client->getProxy();// Proxy the default namespace$hello=$server->test->sayHello(1,2);// test.Hello(1, 2) returns "hello"
getProxy方法接受一个可选参数,该参数指定代理远端服务器的哪个namespace。如果没有提供,缺省的namespace将被代理。
require_once 'Zend/XmlRpc/Client.php';
$client = new Zend_XmlRpc_Client('');
$test = $client->getProxy('test'); // Proxy the "test" namespace
$hello = $test->sayHello(1, 2); // test.Hello(1,2) returns "hello"
如果远端服务器支持namespace的嵌套,也可以通过服务器来代理。比如上例中的服务器有test.foo.bar()函数,它就可以用$test->foo->bar()来调用。
五、错误处理
在调用XML-RPC方法期间会有两种错误发生:HTTP错误和XML-RPC故障。Zend_XmlRpc_Client可以查出每一种,并有能力检测和抓取这两个错误。
HTTP错误
require_once'Zend/XmlRpc/Client.php';$client= newZend_XmlRpc_Client('');try {$client->call('bar', array($arg1,$arg2));} catch (Zend_XmlRpc_Client_HttpException $e) {// $e->getCode() returns 404// $e->getMessage() returns "Not Found"}
XML-RPC故障
XML-RPC故障与PHP的异常相似。它是一个由XML-RPC方法返回的特别类型,它既有错误代码也有错误信息。根据Zend_XmlRpc_Client使用的不同,XML-RPC处理的方式也有所不同。
当调用Call()方法,或是使用服务器代理对象的时候,一个XML-RPC的故障将导致Zend_XmlRpc_Client_FaultException抛出异常。原始XML-RPC故障响应的异常代码和信息将直接映射到各自的键值上。
require_once'Zend/XmlRpc/Client.php';$client= newZend_XmlRpc_Client('');try {$client->call('badMethod');} catch (Zend_XmlRpc_Client_FaultException $e) {// $e->getCode() returns 1// $e->getMessage() returns "Unknown method"}
当Call方法被用来做请求时,Zend_XmlRpc_Client_FaultException将在发生错误时候抛出异常。调用getLastResponse方法时,一个Zend_XmlRpc_Response对象将包含该异常。
当用doRequest方法来做请求时,它将不会抛出异常,由返回的Zend_XmlRpc_Response对象返回所包含异常。该异常也可以由Zend_XmlRpc_Response的isFault方法检测出来
六、Server Introspection
一些XML-RPC服务器在XML-RPC系统下支持事实上的内省方法。Zend_XmlRpc_Client也提供了对拥有这些特性的服务器的支持。 七、从请求到响应在报头中,Zend_XmlRpc_Client使用 Call方法构建了一个请求对象Zend_XmlRpc_Request,并用另一个方法doRequest来发送,后返回一个Zend_XmlRpc_Response对象。
doRequest方法也可以直接拿来用
require_once'Zend/XmlRpc/Client.php';$client= newZend_XmlRpc_Client('');$request= newZend_XmlRpc_Request();$request->setMethod('test.sayHello');$request->setParams(array('foo','bar'));$client->doRequest($request);// $server->getLastRequest() returns instanceof Zend_XmlRpc_Request// $server->getLastResponse() returns instanceof Zend_XmlRpc_Response
无论客户端通过何种方式来调用XML-RPC方法,既可以是call方法,doRequest方法,或是服务器代理,最后一次的请求对象和它的结果响应对象都可以由getLastRequest方法和getLastResponse方法得到。 八、HTTP客户端和测试之前例子总是没有指定HTTP客户端。这些例子中,Zend_XmlRpc_Client的新实例由它的缺省选项创建,并由Zend_XmlRpc_Client自动使用。HTTP客户端能用getHttpClient方法在任何时间取回。在大多数的场合中,缺省建立的HTTP 客户端已经足够。不过,setHttpClient方法允许注入不同的HTTP客户端实例。
在单元测试中,setHttpClient会特别的有用。当结合Zend_Http_Client_Adapter_Test,远端服务器可以被模拟以便测试。该例子在Zend_XmlRpc_Client的单元测试实例中