Yii фреймворк: создание XML-RPC сервера

Владимир | | PHP, Web разработка, Yii.

yii xml rpc

На мой взгляд, 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.