全部博文(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
= new
Zend_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
= new
Zend_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
= new
Zend_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
= new
Zend_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
= new
Zend_XmlRpc_Client
(
''
);
$request
= new
Zend_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的单元测试实例中