CodeIgniter User Guide Version 2.0.0


Классы XML-RPC и XML-RPC Server

Класс XML-RPC позволяет вам отправлять запросы на другой сервер, или установить собственный сервер XML-RPC, принимающий запросы.

Что такое XML-RPC?

Все очень просто — это способ, которым два компьютера могут соединяться друг с другом через интернет, используя XML. Один компьютер, который называется клиент, отправляет запрос XML-RPC другому компьютеру, который называется сервер. Сервер принимает и обрабатывает запрос, и посылает назад ответ клиенту.

Например, используя MetaWeblog API, клиент XML-RPC (обычно десктопный инструмент для публикаций) отправляет запрос серверу XML-RPC, запущенному на сайте. Этот запрос может быть новой темой в блоге, которую нужно опубликовать, или запрос на редактирование существующей темы. Когда сервер XML-RPC принимает этот запрос, он будет изучать его, чтобы определить, какой класс/метод может быть вызван для обработки запроса. После обработки сервер вернет ответное сообщение.

Для более подробной информации можете посетить сайт XML-RPC.

Инициализация класса

Как и большинство других классов, классы XML-RPC и XML-RPCS инициализируются в вашем контроллере посредством функции $this->load->library:

Для того, чтобы загрузить класс XML-RPC, используйте:

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

Загруженный класс доступен как: $this->xmlrpc

Для того, чтобы загрузить класс XML-RPC Server, используйте:

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

Загруженные класс xml-rpcs будет доступен как: $this->xmlrpcs

Примечание:  При использовании класса XML-RPC Server вы должны загрузить ОБА класса — XML-RPC и XML-RPC Server.

Отправка запроса XML-RPC

Для того, чтобы отправить запрос серверу XML-RPC, вы должны указать следующую информацию:

Вот основной пример, как отправить простой пинг Weblogs.com к Ping-o-Matic

$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). Запрос (в этом случае, название и URL вашего сайта) размещается в массиве для транспортировки, и компилируется посредством функции request(). Наконец, подготовленный запрос отправляется. Если метод send_request() возвращает FALSE, мы выведем сообщения об ошибках, возвращенные сервером XML-RPC.

Анатомия запроса

Запрос XML-RPC - это просто данные, которые вы отправляете серверу XML-RPC. Каждый элемент данных в запросе соотносится с параметром запроса. В примере выше присутствуют два параметра: URL и название вашего сайта. Когда сервер XML-RPC принимает ваш запрос, он будет проверять требуемые параметры.

Параметры запроса должны быть расположены в массиве для транспортировки, и каждый параметр может быть одного из семи типов данных (строки, числа, даты и т.д.). Если ваш параметр не строкового типа, включите тип данных в массив запроса.

Вот пример простого массива с тремя параметрами:

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

Если вы используете типы данных кроме строк, или вы используете несколько различных типов данных, разместите каждый параметр в собственном массиве, с указанием типа данных во второй позиции:

$request = array (
                   array('John', 'string'),
                   array('Doe', 'string'),
                   array(FALSE, 'boolean'),
                   array(12345, 'int')
                 );
$this->xmlrpc->request($request);
Раздел Типы данных ниже содержит полный список доступных типов данных.

Создание сервера XML-RPC

Сервер XML-RPC действует как инспектор ГИБДД, ожидая входящие запросы, и переадресуя их к соответствующим функциям для последующей обработки

Чтобы создать ваш собственный сервер XML-RPC, включите инициализацию класса XLM-RPC Server в вашем контроллере там, где вы ожидаете появление запросов, затем установите массив с инструкциями по разбору входящих запросов, которые могут быть переданы соответствующему классу/методу для обработки.

Вот пример:

$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.

Другими словами, если клиент XLM-RPC отправляет запрос для метода new_post, ваш сервер загрузит класс My_blog и вызовет его функцию new_entry. Если пришел запрос метода update_post, ваш сервер загрузит класс My_blog и вызовет функцию update_entry.

Имена функций в примере выше произвольные. Вы самостоятельно решаете, как они будут называться на вашем сервере, или, если вы используете стандартизированные API, как Blogger или MetaWeblog API, вы будете использовать имена функций, указанные в них.

Есть два различных ключа конфигурации, которые вы можете использовать при инициализации серверного класса: debug может быть установлен в TRUE в случае, если включена отладка, и xss_clean может быть установлен в FALSE для предотвращения обработки данных фильтром XSS.

Обработка серверного запроса

Когда сервер XML-RPC получает запросы и загружает класс/метод для обработки, он передает объект методу, содержащему данные, отправленные клиентом.

Используя пример выше, если запрошен метод new_post, сервер будет ожидать существующий класс в соответствии с этим прототипом:

class My_blog extends CI_Controller {

    function new_post($request)
    {

    }
}

Переменная $request - это объект, скомпилированный сервером, который содержит данные, отправленные клиентом XML-RPC. Используя этот объект, вы можете получать доступ к параметрам запроса, включенных вами в обработку запроса. При завершении обработки вы отправите Ответ назад клиенту.

Ниже реальный пример, использующий Blogger API. Один из методов Blogger API - это getUserInfo(). Используя этот метод, клиент XML-RPC может отправлять серверу имя и пароль, и в ответ сервер отправляет информации о конкретном пользователе (ник, ID пользователя, адрес электронной почты и т.д.). Вот так может выглядеть функция обработки:

class My_blog extends CI_Controller {

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

        $this->load->library('xmlrpc');
    
        $parameters = $request->output_parameters();
    
        if ($parameters['1'] != $username AND $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'
                 );

Обратите внимание, что массив выше отформатирован как структура. Это наиболее распространенный тип данных для ответов.

Как с запросами, ответы могут быть одного из семи типов данных, перечисленных в разделе Типы данных.

Отправка ответа об ошибке

Если вы нуждаетесь в отправке клиенту ответа об ошибке, используйте следующее:

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

Первый параметр - это номер ошибки, второй — текст сообщения об ошибке.

Создание ваших собственных клиента и сервера

Для облегчения понимания вышенаписанного, давайте создадим пару контроллеров, которые будут XML-RPC клиентом и сервером. Вы будете использовать клиент для отправки запроса серверу, и получения ответа.

Клиент

Используя текстовый редактор, создайте контроллер с названием xmlrpc_client.php. В нем разместите этот код и сохраните его в вашу директорию applications/controllers/

Примечание: В коде выше мы используем помощник URL. Вы можете найти больше информации на странице Функции помощников.

Сервер

Используя текстовый редактор, создайте контроллер с названием xmlrpc_server.php. Разместите этот код в нем и сохраните в вашу директорию applications/controllers/:

Попробуйте!

Теперь посетите ваш сайт, используя URL, соответствующий этому:

example.com/index.php/xmlrpc_client/

Вы должны увидеть сообщение, отправленное серверу, и его ответ на него, возвращенный вам.

Клиент, которого вы создали, отправляет сообщение ("How's is going?") серверу, вместе с просьбой ответить методом "Greetings". Сервер получает запрос и передает его функции "process", которая возвращает ответ.

Использование ассоциативного массива в параметре запроса

Если вы желаете использовать ассоциативный массив в параметрах вашего метода, вы должны использовать структурный тип данных:

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

You can retrieve the associative array when processing the request in the Server.

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

Справка по функциям XML-RPC

$this->xmlrpc->server()

Устанавливает URL и номер порта сервера, которому отправляется запрос:

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

$this->xmlrpc->timeout()

Устанавливает время таймаута (в секундах), после которого запрос будет отменен:

$this->xmlrpc->timeout(6);

$this->xmlrpc->method()

Устанавливает метод, который будет отвечать от сервера XML-RPC:

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

Где method  — имя метода.

$this->xmlrpc->request()

Принимает массив данных и строит запрос, который будет отправлен серверу XML-RPC:

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

$this->xmlrpc->send_request()

Функция отправки запроса. Возвращает булево TRUE или FALSE, в зависимости от успеха или неудачи. Используйте это в условии.

$this->xmlrpc->set_debug(TRUE);

Включает отладку, которая будет отображать различную информацию и данные об ошибках, полезные при разработке.

$this->xmlrpc->display_error()

Возвращает строкой сообщение об ошибке, если ваш запрос неудачен по некоторым причинам.

echo $this->xmlrpc->display_error();

$this->xmlrpc->display_response()

Возвращает ответ от удаленного сервера. Ответ обычно является ассоциативным массивом.

$this->xmlrpc->display_response();

$this->xmlrpc->send_error_message()

Эта функция позволяет вам отправить сообщение об ошибке от вашего сервера клиенту. Первый параметр - это номер ошибки, второй — текст сообщения об ошибке.

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

$this->xmlrpc->send_response()

Позволяет вам отправить ответ от вашего сервера клиенту. Этому методу должен быть передан массив с корректными данными.

$response = array(
                 array(
                        'flerror' => array(FALSE, 'boolean'),
                        'message' => "Thanks for the ping!"
                     )
                 'struct');
return $this->xmlrpc->send_response($response);

Типы данных

В соответствии со спецификацией XML-RPC есть семь типов значений, которые можно отправлять через XML-RPC: