На мой взгляд, XML-RPC протокол является одним из наиболее удобных способов передачи данных между Интернет-ресурсами. Можно, конечно, поспорить, но на изучение XML-RPC требуется минимальное количество времени, есть множество готовых библиотек, да и используется он очень широко. Поэтому я никогда не понимал, почему разработчики отличного фреймворка Yii решили не включать библиотеку для работы с XML-RPC в дистрибутив. Хотя, возможно, это вопрос времени 🙂
Тем не менее, работать нужно уже сейчас, и в этой статье мы разберём, как решить проблему с помощью сторонних библиотек.
Примечание. Если вас интересует создание XML-RPC клиента, почитайте статью XML-RPC и Yii фреймворк.
Немного теории.
Мы можем использовать два основных подхода при создании XML-RPC сервера.
1) Отдельный скрипт. В этом случае создаём файл с именем вроде xmlrpc.php и помещаем его в корень сайта. В нём будет находиться код обработки XML-RPC запросов. Такой подход используется, например, в WordPress. Достоинство в том, что вам не нужно вносить никаких изменений в код вашего проекта, т.е. XML-RPC интерфейс получается независимым. С другой стороны, независимость приводит к тому, что вам будет гораздо сложнее работать со встроенными библиотеками фреймворка.
2) Использование действий контроллера. Этот вариант гораздо интереснее. Во-первых, вы автоматически получаете доступ ко всем возможностям Yii. Во-вторых, в этом случае XML-RPC методы можно разделить по модулям. Т.е. подключение / отключение модуля будет автоматически подключать / отключать соответствующие XML-RPC методы.
Т.к. реализация первого подхода никакой сложности не представляет (фактически вы можете использовать примеры из документации к вашей библиотеке для работы с XML-RPC), мы рассмотрим второй вариант.
Какие библиотеки можно использовать?
По большому счёту – любые, т.к. подключение сторонних библиотек к Yii выполняется без особых проблем. Я обычно использую библиотеку Incutio XML-RPC Library. Она достаточно простая, работает без проблем и, кроме того, используется в WordPress, а эта CMS используется очень часто.
Переходим к практике.
Шаг 1. Подключаем библиотеку.
Для этого скачиваем библиотеку и сохраняем файл IXR_Library.php
в папку protected/vendors
. Теперь подключить библиотеку можно так:
Yii::import('application.vendors.*'); require_once ('IXR_Library.php');
Этот код можно добавить в любое действие (action
) контроллера.
Шаг 2. Создаём точку входа.
Как я уже говорил, в качестве точки входа мы используем действие контроллера. Код будет выглядеть примерно так:
class MyController extends Controller { ... public function actionXmlrpc() { Yii::import('application.vendors.*'); require_once ('IXR_Library.php'); $server = new IXR_Server(array( 'my.hello' => array($this,'hello'), )); } ... }
В этом методе мы просто создаём объект типа IXR_Server
, конструктору которого нужно передать массив с названиями XML-RPC методов. В данном случае в массиве только один элемент. Ключ этого элемента является названием XML-RPC метода, а значение – именем функции, которую нужно вызвать.
array($this,'hello')
означает, что будет вызван метод hello
данного контроллера.
Тут нужно помнить об одном нюансе. Обычно в XML-RPC запросах не передаются данные сессий. Логин и пароль отправляются в каждом запросе в качестве параметров. Поэтому необходимо, обеспечить доступ к методу actionXmlrpc()
без авторизации. Для этого немного изменим метод accessRules
public function accessRules() { return array( array('allow', // allow all users to perform 'index' and 'view' actions 'actions'=>array('index','view','xmlrpc'), 'users'=>array('*'), ), …, ); }
Шаг 3. Добавляем методы.
Теоретически, можно ограничиться просто добавлением метода hello
, который просто вернет «Hello, world!».
public function hello($args) { return 'Hello, world!'; }
Но в 99% нужно аутентифицировать пользователя. Добавим метод
protected function xmlrpcLogin($username, $password) { $identity = new UserIdentity($username, $password); $identity->authenticate(); if ($identity->errorCode === UserIdentity::ERROR_NONE) { Yii::app()->user->login($identity, 0); return true; } else { return false; } }
Здесь мы используем класс UserIdentity
, который автоматически создаётся фреймворком Yii при создании приложения. В параметрах этого метода нужно передать логин и пароль. В случае успешной аутентификации метод вернёт TRUE, в противном случае – FALSE. Кроме того, данные пользователя будут доступны через Yii::app()->user, т.е. точно также как и при обычной работе с фреймворком.
Теперь перепишем код метода hello.
public function hello($args) { if (!$this->xmlrpcLogin($args[0], $args[1])) { return new IXR_Error(-1, 'You did not provide the correct password'); } return 'Hello, world!'; }
Здесь предполагается, что логин и пароль будут переданы в первом и втором параметрах XML-RPC запроса.
Шаг 4. Проверяем работу.
Для проверки достаточно создать обычный PHP скрипт со следующим кодом.
require_once ('IXR_Library.php'); $client = new IXR_Client('http://my_site.domen/my/xmlrpc'); $client->debug = true; $args = array(); $args[0] = 'login'; $args[1] = 'password'; if (!$client->query('my.hello', $args)) { die('Something went wrong - '.$client->getErrorCode().' : '.$client->getErrorMessage()); } echo $client->getResponse();
Как видите, создание XML-RPC сервера особой сложности не представляет. Конечно, самая сложная работа – это написание самих методов. Но не забывайте, что если у вас уже готов web интерфейс и логика по максимуму вынесена в модели, то вы сможете спокойно использовать её и в XML-RPC методах.
Успехов!
Полезная информация
Новогодний подарок от Inferno Solutions — всем новым клиентам панель ISP бесплатно и 30$ в подарок при заказе VPS в Германии, Украине или Голландии! Укажите при заказе в примечании ISP+30.