摘要
为了给 PHP 提供一种轻型的 RPC 机制来代替 XML-RPC,我们定义了 PHPRPC 协议。该协议可以使纯 PHP 应用程序之间的通讯更方便快速,并且可以与其它实现了该协议的语言的应用程序之间进行通讯。
概述
PHPRPC 是一个工作于 Internet 之上的远程过程调用协议。
PHPRPC 使用 HTTP 协议作为传输协议。PHPRPC 可以使用 HTTP-GET 和 HTTP-POST 两种请求方式。客户端提交的请求和服务器端执行后返回的应答信息在适当的时候通过 PHP serialize() 和 base64_encode() 进行封装,通过 PHP 的 unserialize() 和 base64_decode() 解封装。
远程过程调用中的参数和返回值可以是 PHP 中的任意类型(例如整数类型、浮点数类型、字符串类型、数组、对象等),但对于资源类型只有在产生该资源类型的一方有效,对于自定义对象,通讯双方都包含该对象的类定义时方才有效。
请求
请求使用的是标准的 application/x-www-form-urlencoded 格式。
请求中可以包含以下三个参数,请求参数一律小写,前后顺序任意:
- phprpc_func(必选):该参数表示所调用的服务器端的函数,其值为要调用的函数名,函数名采用明文,无大小写区分,函数名后不跟括号。
- phprpc_args(可选):该参数表示所调用函数所需的参数,参数以数组格式保存,第一个参数的数组下标为 0,第二个参数的数组下标为 1,以此类推。该数组在赋给 phprpc_args 前需要通过 serialize() 序列化,然后通过 base64_encode() 对序列化后的值进行编码。
- phprpc_callback(可选):该参数只用于 JavaScript 客户端,表示服务器端调用执行后,客户端需要回调的JavaScript 程序。其值为经过 base64_encode() 编码的 JavaScript 程序。
如果请求中不包括 phprpc_func 参数,则返回服务器端所提供的远程过程列表。返回格式请参见应答一节。
应答
应答头部的 Content-Type 为 text/plain,X-Powered-By 为 PHPRPC Server/版本号。客户端可通过这两项判断所请求的服务器是否正确。
应答内容为 JavaScript 语法格式。各语句之间用“\r\n”分割。回调函数前的语句之间不可有空行。应答内容的各项有前后顺序。应答内容各项如下:
如果服务器端正确执行了所请求的调用。则返回内容的第一项为过程调用的返回值,第二项为过程调用的参数。
第一项格式如下:
其中 value 为经过编码后的返回值。编码过程为:先对过程调用的返回值进行序列化(调用 PHP serialize() ),然后对序列化后的值进行 base64 编码(调用 base64_encode() )。
第二项格式如下:
其中 value 为经过编码后的过程调用后的参数值。因为所调用的过程在参数传递时可能是引用传递,因此在调用执行后,参数值可能会改变。该项返回的就是改变后的参数值。该项的编码过程与第一项返回值的编码过程相同。
如果服务器端执行所请求的调用时发生了错误,则没有前面两项。接下来的两项是跟错误处理有关的。第一个是出错编号,第二个是出错信息。这两项格式为:
phprpc_errstr='errstr';
上面 errno 为错误编号,为整数明文,如果没有错误,则该数字为 0。errstr 是错误信息,为 base64 编码的字符串。
接下来是服务器端的过程调用中本来应该输出的内容,在这里它们将被重定向为 phprpc_output 项的值。格式为:
这里的 output 也是经过 base64 编码的。
如果客户端的请求中包含了回调参数 phprpc_callback,则将其内容进行解码(调用 base64_decode()),然后直接输出解码后的内容。
实现
该协议目前已经有了 PHP 的服务器端/客户端实现 和 JavaScript 的客户端实现。在使用这两种实现时,无需了解该协议。该协议描述旨在为其他开发语言开发者(例如 Perl、Python、Java 等)在实现该协议时提供参考。其他语言开发者在实现该协议时也可以参考已有的两种实现。
备注
本文所描述的 PHPRPC 协议不同于 Description of PHP-RPC protocol 中所描述的 PHP-RPC 协议。尽管这两个协议都是用来替代 XML-RPC 的专用于 PHP 应用程序间的轻量级 RPC 协议,而且都用到了 php 的序列化(serialize() 和 unserialize())和 BASE64 编码(base64_encode() 和 base64_decode())。但是本文中所描述的 PHPRPC 协议比该文中的 PHP-RPC 协议多了错误处理,服务器端输出重定向,JavaScript 回调支持等,而且请求和应答的内容及格式也不相同。希望读者不要混淆。
