1 教程-内容提要
1.1 CodeIgniter3.1教程——开始
1.2 加载静态内容
1.3 读取新闻条目
1.4 创建新闻条目
2 常规主题
2.1 CodeIgniter URL
2.2 控制器
2.3 保留名称
2.4 视图
2.5 模型
2.6 辅助函数
2.7 使用 CodeIgniter 类库
2.8 创建类库
2.9 使用 CodeIgniter 驱动器
2.10 创建驱动器
2.11 创建核心系统类
2.12 创建附属类
2.13 钩子 - 扩展框架核心
2.14 自动加载资源
2.15 公共函数
2.16 兼容性函数
2.17 URI 路由
2.18 错误处理
2.19 网页缓存
2.20 程序分析
2.21 以 CLI 方式运行
2.22 管理你的应用程序
2.23 处理多环境
2.24 在视图文件中使用 PHP 替代语法
2.25 安全
2.26 PHP 开发规范
3 类库参考
3.1 基准测试类
3.2 缓存驱动器
3.3 日历类
3.4 购物车类
3.5 配置类
3.6 Email 类
3.7 加密类(废弃)
3.8 加密类(新版)
3.9 文件上传类
3.10 表单验证类
3.11 FTP 类
3.12 图像处理类
3.13 输入类
3.14 Javascript 类
3.15 语言类
3.16 加载器类
3.17 迁移类
3.18 输出类
3.19 分页类
3.20 模板解析类
3.21 安全类
3.22 Session 类
3.23 HTML 表格类
3.24 引用通告类
3.25 排版类
3.26 单元测试类
3.27 URI 类
3.28 用户代理类
3.29 XML-RPC 与 XML-RPC 服务器类
3.30 Zip 编码类
4 数据库参考
4.1 数据库快速入门: 示例代码
4.2 数据库配置
4.3 连接你的数据库
4.4 查询
4.5 生成查询结果
4.6 查询辅助函数
4.7 查询构造器类
4.8 事务
4.9 数据库元数据
4.10 自定义函数调用
4.11 查询缓存
4.12 数据库工厂类
4.13 数据库工具类
4.14 数据库驱动器参考
5 辅助函数参考
5.1 数组辅助函数
5.2 验证码辅助函数
5.3 Cookie 辅助函数
5.4 日期辅助函数
5.5 目录辅助函数
5.6 下载辅助函数
5.7 邮件辅助函数
5.8 文件辅助函数
5.9 表单辅助函数
5.10 HTML 辅助函数
5.11 Inflector 辅助函数
5.12 语言辅助函数
5.13 数字辅助函数
5.14 路径辅助函数
5.15 安全辅助函数
5.16 表情辅助函数(废弃)
5.17 字符串辅助函数
5.18 文本辅助函数
5.19 排版辅助函数
5.20 URL 辅助函数
5.21 XML 辅助函数

XML-RPC 与 XML-RPC 服务器类

2017-12-03 20:00:17
linefo
543
最后编辑:linefo 于 2017-12-03 21:06:55

XML-RPC 与 XML-RPC 服务器类

CodeIgniter 的 XML-RPC 类允许你向另一个服务器发送请求, 或者建立一个你自己的 XML-RPC 服务器来接受请求。

什么是 XML-RPC ?

这是一种在两台计算机之间使用 XML 通过互联网进行通信的简单方法。 一台计算机 , 我们称之为客户端 , 发送一个 XML-RPC 请求给另外一台计算机, 我们称之为服务器,当服务器收到请求时,对其进行处理然后将结果返回给客户端。

例如,使用 MetaWeblog API 时,XML-RPC 客户端(通常是桌面发布工具) 将会发送请求到你站点上的 XML-RPC 服务器,这个请求可能是发布一篇新博客, 或者编辑一篇已有的博客。当 XML-RPC 服务器收到该请求时,它会决定使用 哪个类和方法来处理该请求,请求处理完成后,服务器将发送一条回复消息。

关于 XML-RPC 的规范,你可以查看 XML-RPC 的网站。

使用 XML-RPC 类

初始化类

跟 CodeIgniter 中的其他类一样,可以在你的控制器中使用 $this->load->library() 方法加载 XML-RPC 类和 XML-RPC 服务器类。

加载 XML-RPC 类如下:

$this->load->library('xmlrpc');

一旦加载,XML-RPC 类就可以像下面这样使用:

$this->xmlrpc

加载 XML-RPC 服务器类如下:

$this->load->library('xmlrpc');
$this->load->library('xmlrpcs');

一旦加载,XML-RPC 服务器类就可以像下面这样使用:

$this->xmlrpcs

注解

当使用 XML-RPC 服务器类时,xmlrpc 和 xmlrpcs 都需要加载。

发送 XML-RPC 请求

向 XML-RPC 服务器发送一个请求,你需要指定以下信息:

  • 服务器的 URL
  • 你想要调用的服务器方法
  • 请求 数据(下面解释)

下面是个基本的例子,向 Ping-o-Matic 发送一个简单的 Weblogs.com ping 请求。

$this->load->library('xmlrpc');

$this->xmlrpc->server('http://rpc.pingomatic.com/', 80);
$this->xmlrpc->method('weblogUpdates.ping');

$request = array('My Photoblog', 'http://www.my-site.com/photoblog/');
$this->xmlrpc->request($request);

if ( ! $this->xmlrpc->send_request())
{
    echo $this->xmlrpc->display_error();
}

解释

上面的代码初始化了一个 XML-RPC 类,并设置了服务器 URL 和要调用的方法 (weblogUpdates.ping)。然后通过 request() 方法编译请求, 例子中请求是一个数组(标题和你网站的 URL)。最后,使用 send_request() 方法发送完整的请求。如果发送请求方法返回 FALSE ,我们会显示出 XML-RPC 服务器返回的错误信息。

请求解析

XML-RPC 请求就是你发送给 XML-RPC 服务器的数据,请求中的每一个数据也被称为请求参数。 上面的例子中有两个参数:你网站的 URL 和 标题。当 XML-RPC 服务器收到请求后, 它会查找它所需要的参数。

请求参数必须放在一个数组中,且数组中的每个参数都必须是 7 种数据类型中的一种 (string、number、date 等),如果你的参数不是 string 类型,你必须在请求数组中 指定它的数据类型。

下面是三个参数的简单例子:

$request = array('John', 'Doe', 'www.some-site.com');
$this->xmlrpc->request($request);

如果你的数据类型不是 string ,或者你有几个不同类型的数据,那么你需要将 每个参数放到它单独的数组中,并在数组的第二位声明其数据类型:

$request = array(
    array('John', 'string'),
    array('Doe', 'string'),
    array(FALSE, 'boolean'),
    array(12345, 'int')
);
$this->xmlrpc->request($request);

下面的 数据类型 一节列出了所有支持的数据类型。

创建一个 XML-RPC 服务器

XML-RPC 服务器扮演着类似于交通警察的角色,等待进入的请求, 并将它们转到恰当的函数进行处理。

要创建你自己的 XML-RPC 服务器,你需要先在负责处理请求的控制器中初始化 XML-RPC 服务器类,然后设置一个映射数组,用于将请求转发到合适的类和方法, 以便进行处理。

下面是个例子:

$this->load->library('xmlrpc');
$this->load->library('xmlrpcs');

$config['functions']['new_post'] = array('function' => 'My_blog.new_entry');
$config['functions']['update_post'] = array('function' => 'My_blog.update_entry');
$config['object'] = $this;

$this->xmlrpcs->initialize($config);
$this->xmlrpcs->serve();

上例中包含了两个服务器允许的请求方法,数组的左边是允许的方法名, 数组的右边是当请求该方法时,将会映射到的类和方法。

其中,'object' 是个特殊的键,用于传递一个实例对象,当映射的方法无法使用 CodeIgniter 超级对象时,它将是必须的。

换句话说,如果 XML-RPC 客户端发送一个请求到 new_post 方法, 你的服务器会加载 My_blog 类并调用 new_entry 函数。如果这个请求是到 update_post 方法的,那么你的服务器会加载 My_blog 类并调用 update_entry 方法。

上面例子中的函数名是任意的。你可以决定这些函数在你的服务器上叫什么名字, 如果你使用的是标准的 API,比如 Blogger 或者 MetaWeblog 的 API, 你必须使用标准的函数名。

这里还有两个附加的配置项,可以在服务器类初始化时配置使用。debug 设为 TRUE 以便调试, xss_clean 可被设置为 FALSE 以避免数据被安全类库的 xss_clean 函数过滤。

处理服务器请求

当 XML-RPC 服务器收到请求并加载类与方法来处理时,它会接收一个包含客户端发送的数据参数。

在上面的例子中,如果请求的是 new_post 方法,服务器请求的类与方法会像这样:

class My_blog extends CI_Controller {

    public function new_post($request)
    {

    }
}

$request 变量是一个由服务端汇集的对象,包含由 XML-RPC 客户端发送来的数据。 使用该对象可以让你访问到请求参数以便处理请求。请求处理完成后, 发送一个响应返回给客户端。

下面是一个实际的例子,使用 Blogger API 。Blogger API 中的一个方法是 getUserInfo(), XML-RPC 客户端可以使用该方法发送用户名和密码到服务器,在服务器返回的数据中, 会包含该用户的信息(昵称,用户 ID,Email 地址等等)。下面是处理的代码:

class My_blog extends CI_Controller {

    public function getUserInfo($request)
    {
        $username = 'smitty';
        $password = 'secretsmittypass';

        $this->load->library('xmlrpc');

        $parameters = $request->output_parameters();

        if ($parameters[1] != $username && $parameters[2] != $password)
        {
            return $this->xmlrpc->send_error_message('100', 'Invalid Access');
        }

        $response = array(
            array(
                'nickname'  => array('Smitty', 'string'),
                'userid'    => array('99', 'string'),
                'url'       => array('http://yoursite.com', 'string'),
                'email'     => array('jsmith@yoursite.com', 'string'),
                'lastname'  => array('Smith', 'string'),
                'firstname' => array('John', 'string')
            ),
                         'struct'
        );

        return $this->xmlrpc->send_response($response);
    }
}

注意

output_parameters() 函数获取一个由客户端发送的请求参数数组。 上面的例子中输出参数将会是用户名和密码。

如果客户端发送的用户名和密码无效的话,将使用 send_error_message() 函数返回错误信息。

如果操作成功,客户端会收到包含用户信息的响应数组。

格式化响应

和请求一样,响应也必须被格式化为数组。然而不同于请求信息,响应数组 只包含一项 。 该项可以是一个包含其他数组的数组,但是只能有一个主数组,换句话说, 响应的结果大概是下面这个样子:

$response = array('Response data', 'array');

但是,响应通常会包含多个信息。要做到这样,我们必须把各个信息放到他们自己的数组中, 这样主数组就始终只有一个数据项。下面是一个例子展示如何实现这样的效果:

$response = array(
    array(
        'first_name' => array('John', 'string'),
        'last_name' => array('Doe', 'string'),
        'member_id' => array(123435, 'int'),
        'todo_list' => array(array('clean house', 'call mom', 'water plants'), 'array'),
    ),
    'struct'
);

注意:上面的数组被格式化为 struct,这是响应最常见的数据类型。

如同请求一样,响应可以是七种数据类型中的一种,参见 数据类型 一节。

发送错误信息

如果你需要发送错误信息给客户端,可以使用下面的代码:

return $this->xmlrpc->send_error_message('123', 'Requested data not available');

第一个参数为错误编号,第二个参数为错误信息。

创建你自己的客户端与服务端

为了帮助你理解目前为止讲的这些内容,让我们来创建两个控制器,演示下 XML-RPC 的客户端和服务端。你将用客户端来发送一个请求到服务端并从服务端收到一个响应。

客户端

使用文本编辑器创建一个控制器 Xmlrpc_client.php ,在这个控制器中, 粘贴以下的代码并保存到 applications/controllers/ 目录:

<?php

class Xmlrpc_client extends CI_Controller {

    public function index()
    {
        $this->load->helper('url');
        $server_url = site_url('xmlrpc_server');

        $this->load->library('xmlrpc');

        $this->xmlrpc->server($server_url, 80);
        $this->xmlrpc->method('Greetings');

        $request = array('How is it going?');
        $this->xmlrpc->request($request);

        if ( ! $this->xmlrpc->send_request())
        {
            echo $this->xmlrpc->display_error();
        }
        else
        {
            echo '<pre>';
            print_r($this->xmlrpc->display_response());
            echo '</pre>';
        }
    }
}
?>

注解

上面的代码中我们使用了一个 URL 辅助函数,更多关于辅助函数的信息, 你可以阅读 这里

服务端

使用文本编辑器创建一个控制器 Xmlrpc_server.php ,在这个控制器中, 粘贴以下的代码并保存到 applications/controllers/ 目录:

<?php

class Xmlrpc_server extends CI_Controller {

    public function index()
    {
        $this->load->library('xmlrpc');
        $this->load->library('xmlrpcs');

        $config['functions']['Greetings'] = array('function' => 'Xmlrpc_server.process');

        $this->xmlrpcs->initialize($config);
        $this->xmlrpcs->serve();
    }


    public function process($request)
    {
        $parameters = $request->output_parameters();

        $response = array(
            array(
                'you_said'  => $parameters[0],
                'i_respond' => 'Not bad at all.'
            ),
            'struct'
        );

        return $this->xmlrpc->send_response($response);
    }
}

尝试一下

现在使用类似于下面这样的链接访问你的站点:

example.com/index.php/xmlrpc_client/

你应该能看到你发送到服务端的信息,以及服务器返回的响应信息。

在客户端,你发送了一条消息("How's is going?")到服务端, 随着一个请求发送到 "Greetings" 方法。服务端收到这个请求并映射到 "process" 函数,然后返回响应信息。

在请求参数中使用关联数组

如果你希望在你的方法参数中使用关联数组,那么你需要使用 struct 数据类型:

$request = array(
    array(
        // Param 0
        array('name' => 'John'),
        'struct'
    ),
    array(
        // Param 1
        array(
            'size' => 'large',
            'shape'=>'round'
        ),
        'struct'
    )
);

$this->xmlrpc->request($request);

你可以在服务端处理请求信息时获取该关联数组。

$parameters = $request->output_parameters();
$name = $parameters[0]['name'];
$size = $parameters[1]['size'];
$shape = $parameters[1]['shape'];

数据类型

根据 XML-RPC 规范 一共有七种不同的数据类型可以在 XML-RPC 中使用:

  • int or i4
  • boolean
  • string
  • double
  • dateTime.iso8601
  • base64
  • struct (contains array of values)
  • array (contains array of values)

类参考

class CI_Xmlrpc
initialize([$config = array()])
参数:
  • $config (array) -- Configuration data
返回类型:

void

初始化 XML-RPC 类,接受一个包含你设置的参数的关联数组。

server($url[, $port = 80[, $proxy = FALSE[, $proxy_port = 8080]]])
参数:
  • $url (string) -- XML-RPC server URL
  • $port (int) -- Server port
  • $proxy (string) -- Optional proxy
  • $proxy_port (int) -- Proxy listening port
返回类型:

void

用于设置 XML-RPC 服务器端的 URL 和端口:

$this->xmlrpc->server('http://www.sometimes.com/pings.php', 80);

支持基本的 HTTP 身份认证,只需简单的将其添加到 URL中:

$this->xmlrpc->server('http://user:pass@localhost/', 80);
timeout($seconds = 5)
参数:
  • $seconds (int) -- Timeout in seconds
返回类型:

void

设置一个超时时间(单位为秒),超过该时间,请求将被取消:

$this->xmlrpc->timeout(6);
This timeout period will be used both for an initial connection to
the remote server, as well as for getting a response from it. Make sure you set the timeout before calling send_request().
method($function)
参数:
  • $function (string) -- Method name
返回类型:

void

设置 XML-RPC 服务器接受的请求方法:

$this->xmlrpc->method('method');

其中 method 参数为请求方法名。

request($incoming)
参数:
  • $incoming (array) -- Request data
返回类型:

void

接受一个数组参数,并创建一个发送到 XML-RPC 服务器的请求:

$request = array(array('My Photoblog', 'string'), 'http://www.yoursite.com/photoblog/');
$this->xmlrpc->request($request);
send_request()
返回:TRUE on success, FALSE on failure
返回类型:bool

发送请求的方法,成功返回 TRUE,失败返回 FALSE ,可以用在条件判断里。

display_error()
返回:Error message string
返回类型:string

当请求失败后,返回错误信息。

echo $this->xmlrpc->display_error();
display_response()
返回:Response
返回类型:mixed

远程服务器接收请求后返回的响应,返回的数据通常是一个关联数组。

$this->xmlrpc->display_response();
send_error_message($number, $message)
参数:
  • $number (int) -- Error number
  • $message (string) -- Error message
返回:

XML_RPC_Response instance

返回类型:

XML_RPC_Response

这个方法允许你从服务器发送一个错误消息到客户端。 第一个参数是错误编号,第二个参数是错误信息。

return $this->xmlrpc->send_error_message(123, 'Requested data not available');