`

在PHP中利用XML技术构造远程服务

阅读更多

未来的Web将是以服务为中心的Web,XML_RPC标准使得编写和应用服务变得非常简单。本文介绍XML_RPC标准及其PHP实现,并通过实例示范了如何在PHP中开发XML_RPC服务和客户程序。 

一、服务式Web 
从内容提供商所采用的简单方法到UDDI(Universal Description,Discovery and Integration)的未来构想,业界已经有大量关于“服务式Web”的说明和评论。就Web的初创阶段来说,它只是一个文档的集散地,提供的只是一些可浏览的信息。随着Web的发展,在Web上运行服务越来越具有吸引力。未来,Web将成为企业为客户和其他企业提供便捷服务的载体。B2B和B2C模式间的协同就可以看成是一种服务式Web。 

一个很重要的问题是,Web上究竟可以提供哪些服务?Web能够提供的服务非常多,其中有些服务现在已经在使用,有些服务在不久的将来就会出现。为了说明问题,下面列出了一小部分可以通过Web提供的服务: 

面向主题的垂直搜索引擎。 
供用户查找信息的知识库。 
用户可以请教问题的专家系统。 
银行服务。 
新闻和信息出版服务。 
数字化支付相关的服务。 
图形处理服务。 
卫生和健康服务。 

那么,企业和组织通过Web提供服务的正确途径是什么呢?这是一个很重要的问题。今天,有些服务提供HTML界面,它们通过文档的形式提供服务,但在服务界面的背后隐藏着什么?在占领Web的竞赛中,Web浏览器并不孤单,移动电话、手持设备以及微波炉之类的设备都想要访问Web、查询数据库、转换数据、提取信息,等等。要实现真正的服务式Web,在表现层(HTML)之下应该还有另外一层。 

二、XML_RPC标准 
XML或许是近10年来最为重要的标准,XML词汇表(Vocabulary)为企业构造服务环境提供了基石。要构建服务式Web就有必要学习XML_RPC标准,这不仅是因为XML_RPC对于把服务放到Web上很有用,而且因为XML_RPC是一种已经成形的、很容易采用的标准。对于B2B服务来说,提供服务的标准是极其重要的,共同遵循标准的公司可以利用其它公司提供的服务获得快速的增长。无法想象在各种私有的服务标准之上可以建立起真正的服务式Web,服务必须有一种可以遵循的标准。 

XML_RPC是一种面向Internet分布式处理的标准。RPC即为Remote Procedure Call(远程过程调用)的缩写,它是一种远程调用机制,用于调用可能驻留在其他机器之上以及可能用其他语言编写的过程。远程过程调用是分布式计算的重要支柱。例如,在一个分布式计算环境中,我们可以寻找和利用在其他机器上运行的执行加法和减法操作的过程,执行加法操作的过程可能用APL编写、在RS6000机器上运行,执行减法操作的过程可能用C编写、在Unix上运行。其他要使用这种分布式计算器的开发者同样可以利用它们,或者他也可以选用另外更好的计算器。 

在RPC中,过程(Procedure)是最主要的构件,服务器提供的就是供客户端调用的过程。过程可以接收参数并返回结果。XML_RPC以HTTP作为协议载体,通过发送和接收数据的XML词汇表实现RPC机制。XML_RPC服务器接收XML_RPC请求并返回XML_RPC应答,XML_RPC客户程序发送XML_RPC请求并接收XML_RPC应答。服务器和客户必须按照XML_RPC标准的要求处理应答和请求。 

三、XML_RPC协议 
完整的XML_RPC规范可以在http://www.xmlrpc.com/spec找到。下面是其要点说明。 

3.1 XML_RPC请求 

XML_RPC请求应该是HTTP POST请求,它的正文是XML格式。请求的XML部分格式如下: 

<?xml version="1.0" ?>
<methodCall>
<methodName>examples.getStateName</methodName>
<params>
<param>
<value><i4>41</i4></value>
</param>
</params>
</methodCall>


指定数据发送到哪里的URL并未在这里指定。如果服务器专门用来进行RPC处理,它可能是“/”。上述XML文档中的有效载荷是一个“methodCall”结构。methodCall必须包含一个“methodName”子元素,“methodName”子元素包含一个描述待调用方法的字符串。如何解释“methodName”的内容完全由服务器决定,例如它可以是一个执行文件的名字,可以是数据库中记录的名字,或者任何其他东西。如果过程接收参数,“methodCall”可以包含一个“params”元素以及若干个“param”子元素。每一个“param”元素包含一个带有类型描述符的值,类型描述符如下表所示: 


标记 说明 
<i4>或<int> 四字节的带符号整数,如12 
<boolean> 0(false),或1(true) 
<string> 字符串,如“Hello World” 
<double> 双精度带符号浮点数,如-12.214 
<dateTime.iso8601> 日期/时间,如19980717T14:08:55 
<base64> base64编码的二进制数据,如eW91IGbid0IHJlQgdGhpcyE? 


3.1.1 结构 

值可以是一个结构,结构用<struct>元素描述。每个<struct>包含多个<member>,每个<member>包含一个<name>和一个<value>。下面是一个由两个元素构成的结构: 

<struct>
<member>
<name>name</name>
<value><string>member1</string></value>
</member>
<member>
<name>member2</name>
<value><i4>19</i4></value>
</member>
</struct>


<struct>可以嵌套,任意<value>可以包含<struct>或者任意其它类型,包括<array>。 

3.1.2 数组 

值可以是数组类型,数组用<array>元素描述。每个<array>元素包含一个<data>元素,<data>元素里面可以包含任意多个<value>元素。下面是数组元素的一个例子: 

<array>
<data>
<value><boolean>0</boolean></value>
<value><i4>9</i4></value>
<value><string>Hello</string></value>
</data>
</array>


<array>元素没有名字。如前例所示,<array>元素的值可以是各种类型。<array>元素可以嵌套,任何<value>都可以包含<array>或者其他类型,如上面介绍的<struct>。 

3.2 XML_RPC应答 

XML_RPC应答是一个HTTP应答,内容类型是text/xml。应答正文的格式如下: 

<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><string>ABCDEFG</string></value>
</param>
</params>
</methodResponse>


<methodResponse>可能包含一个<params>结构,或者可能包含一个<fault>结构,具体由过程调用是否成功决定。<params>结构与XML请求中的一样,<fault>元素的语法如下: 

<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><int>4</int></value>
</member>
<member>
<name>faultString</name>
<value><string>Error!</string></value>
</member>
</struct>
</value>
</fault>


四、基于XML_RPC的Web服务 
利用XML_RPC构造和使用服务是很方便的。企业为自己提供的各种服务部署XML_RPC服务器,用户、客户软件和客户企业就可以使用这种服务构造出高端服务或者面向最终用户的应用。这种提供更有效、廉价和优质服务的竞争将极大地提高应用服务的质量。 

但这里还存在一些问题有待解决,例如怎样编目、索引、搜索Web上的服务?UDDI试图解决这个问题,不过这个标准并不简单,而且业界对它的反应也尚未明了。然而,在企业内部应用XML_RPC不仅能够改善代码的可重用性,而且还会带来一种全新的分布式计算模式,在此后的数年中它必将成为一种重要的知识财富。XML_RPC的发展从解决分布式计算问题以及成为服务式Web的基本层面开始,从而获得了一个非常好的开端,其后必将紧随着人们对该标准的热衷。既然如此,现在就让我们来看看XML_RPC的实际应用吧! 

4.1 在PHP中应用XML_RPC 

对于提供Web服务来说,PHP是一种非常理想的语言。我们只需编写好PHP代码然而把它放到一个合适的位置,就立即有了一个可通过URL“调用”的服务。PHP中的XML_RPC实现可能复杂也可能简单,但我们拥有许多种选择。这里我们选用的是来自Useful Information Company的XML_RPC实现,它的代码和文档可以从http://xmlrpc.usefulinc.com/下载。 

这个XML_RPC实现的基本类涉及两个文件: 

xmlrpc.inc:包含XML_RPC的php客户端所需要的类 

xmlrpcs.inc:包含XML_RPC的php服务器所需要的类 

4.2 客户端 

编写XML_RPC客户端意味着: 

1.创建一个XML_RPC请求消息 

2.设置XML_RPC参数 

3.创建一个XML_RPC消息 

4.发送消息 

5.获得应答 

6.解释应答 

请看下面这个例子: 

<?php
$f=new xmlrpcmsg('examples.getStateName',array(new xmlrpcval(14, "int")));
$c=new xmlrpc_client("/RPC2", "betty.userland.com", 80);
$r=$c->send($f);
$v=$r->value();
if (!$r->faultCode()) {
print "状态代码". $HTTP_POST_VARS["stateno"] . "是" .
$v->scalarval() . "<BR>";
print "<HR>这是服务器的应答<BR><PRE>" .
htmlentities($r->serialize()). "</PRE><HR>\n";
} else {
print "错误: ";
print "代码: " . $r->faultCode() . 
" 原因: '" .$r->faultString()."'<BR>";
}
?>


在这个例子中,我们先创建了一个调用“examples.getStateName”方法的XML_RPC消息,并传递了一个类型为“int”值为14的整数参数。然后,我们创建了一个描述待调用URL(路径、域和端口)的客户。接着,我们发送了消息,接收应答对象并检查错误。如果不存在错误,我们就显示结果。 

编写RPC客户程序时要用到的主要函数如下: 

创建客户用: 

$client=new xmlrpc_client($server_path, $server_hostname, $server_port); 

发送消息的方法是: 

$response=$client->send($xmlrpc_message); 

它返回的是xmlrpcresp的一个实例。我们所传递的消息是xmlrpcmsg的实例,它用如下方法创建: 

$msg=new xmlrpcmsg($methodName, $parameterArray); 

methodName是待调用的方法(过程)的名字,parameterArray是xmlrpcval对象的php数组。例如: 

$msg=new xmlrpcmsg("examples.getStateName", array(new xmlrpcval(23, "int"))); 

xmlrpcval对象可以用如下形式创建: 

<?php
$myVal=new xmlrpcval($stringVal);
$myVal=new xmlrpcval($scalarVal, "int" | "boolean" | "string" | "double" | "dateTime.iso8601" | "base64");
$myVal=new xmlrpcval($arrayVal, "array" | "struct");
?>


第一种形式创建的是xmlrpc字符串值。第二种形式创建的是描述值和类型的值。第三种形式通过在数组之类的结构中组合其他xmlrpc值创建复杂的对象,例如: 

<?php
$myArray=new xmlrpcval(array(new xmlrpcval("Tom"), new xmlrpcval("Dick"),new xmlrpcval("Harry")), "array");
$myStruct=new xmlrpcval(array( 
"name" => new xmlrpcval("Tom"),
"age" => new xmlrpcval(34, "int"),
"geek" => new xmlrpcval(1, "boolean")),"struct");
?>


应答对象是xmlrpcresp类型,通过调用客户对象的send方法获得。在服务器端,我们可以通过如下方式创建xmlrpcresp类型的对象: 

$resp=new xmlrpcresp($xmlrpcval); 

而在客户端,则使用如下方法从应答获取xmlrpcval: 

$xmlrpcVal=$resp->value(); 

接下来我们就可以用下面这种方式获取描述应答结果的PHP变量: 

$scalarVal=$val->scalarval(); 

对于复杂的数据类型,有两个函数非常有用,这两个函数都在xmlrpc.inc内: 

$arr=xmlrpc_decode($xmlrpc_val); 

该函数返回一个PHP数组,其中包含了xmlrpcval变量$xmlrpc_val之内的数据,这些数据已经被转换成PHP本身具有的变量类型。 

$xmlrpc_val=xmlrpc_encode($phpval); 

该函数返回一个xmlrpcval类型的值,其中包含了$phpval描述的PHP数据。对于数组和结构,此方法能够进行递归分析。注意,这里不存在对非基本数据类型(如base-64数据,或者日期-时间数据)的支持。 

4.3 服务器端 

利用xmlrpcs.inc提供的类编写服务非常简单。要创建一个服务,我们按照如下方式创建xmlrpc_server的实例: 

<?php
$s=new xmlrpc_server( array("examples.myFunc" =>
array("function" => "foo")));
?> 

传递给xmlrpc_server构造函数的是一个联合数组的联合数组。过程“examples.myFunc”调用“foo”函数,由于这个原因foo被称为方法句柄。 

编写方法句柄很简单。下面是一个方法句柄的骨架: 

<?php
function foo ($params) {
global $xmlrpcerruser; // 引入用户错误代码值
// $params是一个xmlrpcval对象的数组
if ($err) {
// 错误条件
return new xmlrpcresp(0, $xmlrpcerruser+1, // 用户错误1
"Error!");
} else {
// 成功
return new xmlrpcresp(new xmlrpcval("Fine!", "string"));
}
}
?>


可以看到,程序检查了错误,如存在错误则返回错误(从$xmlrpcerruser+1开始);否则如果一切正常,则返回描述操作成功信息的xmlrpcresp。 

五、应用实例 
在下面这个例子中我们将构造一个服务。对于给定的数值n,服务返回n*2。客户端利用该服务计算5*2的值。 

服务器端的代码如下: 

<?php
include("xmlrpc.inc");
include("xmlrpcs.inc");
function foo ($params)
{
global $xmlrpcerruser; // 引入用户错误代码值
// $params是xmlrpcval对象的一个数组
$vala=$params->params[0];
$sval=$vala->scalarval();
$ret=$sval*2;
return new xmlrpcresp(new xmlrpcval($ret, "int"));
}
$s=new xmlrpc_server( array("product" =>
array("function" => "foo")));
?>


客户端代码如下: 

<?php
include("xmlrpc.inc");
if ($HTTP_POST_VARS["number"]!="") {
$f=new xmlrpcmsg('product',array(new xmlrpcval($HTTP_POST_VARS["number"], "int")));
$c=new xmlrpc_client("/xmlrpc/servfoo.php", "luigi.melpomenia.com.ar", 80);
$c->setDebug(0);
$r=$c->send($f);
$v=$r->value();
if (!$r->faultCode()) {
print "Number ". $HTTP_POST_VARS["number"] . " is " .
$v->scalarval() . "<BR>";
print "<HR>来自服务器的结果!<BR><PRE>" .
htmlentities($r->serialize()). "</PRE><HR>\n";
} else {
print "操作失败: ";
print "代码: " . $r->faultCode() .
" 原因: '" .$r->faultString()."'<BR>";
}
}
print "<FORM METHOD=\"POST\">
<INPUT NAME=\"number\" VALUE=\"${number}\">
<input type=\"submit\" value=\"go\" name=\"submit\"></FORM><P>
输入一个数值";
?>


结束语:XML_RPC服务的运作还涉及其他许多基础设施和基础工作,如分布式过程的编目和索引机制,又如在编程语言中处理XML_RPC的更好接口等。有关XML_RPC和服务式Web的报道非常多,让我们密切关注它们的发展吧!

分享到:
评论

相关推荐

    PHP中XML-RPC构造WebService.pdf

    本文主要关注XML-RPC,它利用HTTP作为传输协议,XML作为数据格式,实现远程过程调用。 #### 三、XML-RPC简介 XML-RPC是一种轻量级的协议,允许在不同操作系统和语言之间通过HTTP协议发送和接收XML数据。其核心优势...

    PHP中使用XML-RPC构造Web-Service简单入门.doc

    在PHP 4和5中,除了这个扩展,还可以使用PEAR库中的XML-RPC组件,即使没有安装xmlrpc扩展,也能独立实现XML-RPC协议的交互。 **安装XML-RPC扩展** 在Windows环境下,你需要将php_xmlrpc.dll文件放到系统目录下,并...

    PHP中使用XML-RPC构造Web_Service简单入门.doc

    此外,在PHP的PEAR库中也提供了对XML-RPC的支持,无论是在PHP 4还是PHP 5环境下,都可以通过PEAR::XML_RPC来实现XML-RPC的交互功能。 #### 安装xmlrpc扩展 对于想要使用XML-RPC构建Web Service的开发者来说,确保...

    php-xml

    在PHP中处理XML主要涉及到以下几个知识点: 1. **DOM(Document Object Model)解析**: PHP提供了DOM扩展来处理XML文档,允许开发者以树形结构来操作XML。例如,可以使用`DOMDocument`类加载XML文件,然后通过`...

    freeswitch xml_curl模块使用

    在本文中,我们将深入探讨Freeswitch中的XML_CURL模块及其使用方法,特别是在与PHP集成时如何生成XML文件,以及如何用它来替代传统的directory、ivr(交互式语音响应)和dialplan配置。 Freeswitch是一个开源的软...

    转 主题:实战WebService I: XML-PRC篇(基于php)

    在博文《实战WebService I: XML-RPC篇(基于php)》中,作者通过具体的代码示例,详细介绍了如何在PHP环境中搭建和使用XML-RPC服务。文章可能涵盖了创建XML-RPC服务器、定义可调用的方法、创建XML-RPC客户端以及如何...

    json和xml比较

    2. JSON 格式目前在 Web Service 中推广还属于初级阶段 JSON 和 XML 都有其优点和缺点。JSON 简洁、易于解析,适合网络传输;XML 则格式统一、符合标准,易于与其他系统进行远程交互。但是,无论是 JSON 还是 XML,...

    xml基础以及攻击防御1

    XML(eXtensible Markup Language)是一种用于标记数据的语言,广泛应用于数据交换、配置文件、Web服务等领域。然而,XML的某些特性可能导致安全问题,尤其是XML External Entity (XXE) 攻击。XXE攻击是通过利用XML...

    [其他类别]xml-rpc协议 2.2_xmlrpc-2.2.zip

    在"xml-rpc-2.2.zip"这个压缩包中,可能包含的是XML-RPC协议2.2版本的相关资料和库文件,用于理解和应用XML-RPC技术。 XML-RPC的基本工作原理是这样的: 1. **请求构造**:客户端将方法名和参数封装成一个XML文档...

    PHP webservice教程,soap wsdl密码验证,webservice高级应用

    在IT行业中,Web服务是一种允许不同应用程序之间进行通信的关键技术。PHP作为一款广泛使用的服务器端脚本语言,提供了创建Web服务的能力。本教程将聚焦于PHP的Web服务实现,特别是SOAP(Simple Object Access ...

    XXE漏洞详解【内含vulnhub靶场XXE Lab:1详解】

    2. 远程命令执行(RCE):在某些环境中,如果XML解析器支持特定协议(如`expect`),攻击者可以利用此漏洞执行系统命令。 3. 内网探测:攻击者可以利用XXE漏洞探测内网中的服务和设备状态。 4. DoS攻击:通过大量...

    获取Alexa排名数据的PHP程序代码

    总的来说,了解如何使用PHP获取Alexa排名可以帮助我们更好地理解网络数据分析的过程,同时也展示了如何使用HTTP请求和XML解析技术来与远程服务进行交互。在实际项目中,这样的技能是非常有价值的。

    如何通过WEB_SERVICES远程调用MOSS系统的数据

    在本主题中,我们将深入探讨如何利用Web Services远程调用MOSS系统的数据。 1. **理解Web Services** - Web Services基于标准的XML(Extensible Markup Language)和SOAP(Simple Object Access Protocol)协议,...

    XMLRPC调用webservice

    在实际应用中,Web服务可能提供更复杂的接口,包括多个方法和参数,以及处理错误和异常的能力。XMLRPC的优势在于其简单性和跨平台性,但相比其他如SOAP或RESTful API,它的灵活性和扩展性相对较弱。理解XMLRPC的工作...

    SCAN_XXE:利用XML XXE漏洞

    在"SCAN_XXE:利用XML XXE漏洞"的主题中,我们将深入探讨这一安全威胁及其防范措施。 XML是可扩展标记语言(eXtensible Markup Language),广泛用于数据交换和配置文件。XML解析器在处理文档时,会识别并处理实体...

    PHP实例开发源码—闪速码JAVA短信接口SDK下载带demo.zip

    3. PHP的HTTP请求处理:理解如何在PHP中构造和发送GET或POST请求,以及处理返回的JSON或XML响应。 4. PHP的错误处理和日志记录:在调用外部服务时,良好的错误处理和日志记录至关重要。PHP的try-catch结构和error_...

    php获取本地图片文件并生成xml文件输出具体思路

    在PHP中,获取本地图片文件并生成XML文件是一种常见的数据组织和传输方式。这篇描述涉及的技术点主要包括PHP文件操作、目录...这样的方法在需要跨平台共享或存储图片信息时非常有用,特别是在Web服务和移动应用开发中。

    php XmlRPC 官方文档

    XML-RPC for PHP 是一个功能强大的远程过程调用(Remote Procedure Call, RPC)工具,它允许在不同系统之间进行简单高效的数据交换与方法调用。本篇文档将详细介绍 PHP XML-RPC 的基本概念、安装配置方法以及具体...

    PHP 5.2中文手册

    在PHP 5.2中,基础语法包括变量声明、数据类型(如整型、浮点型、字符串、数组、布尔型、NULL)、流程控制(如if-else、switch、for、while循环)、函数和类的定义与调用。 二、对象和类 PHP 5引入了全面的对象模型...

Global site tag (gtag.js) - Google Analytics