18.2. Zend_XmlRpc_Client

18.2.1. Введение

Использование Zend_XmlRpc_Client очень похоже на использование объектов SoapClient (расширение SOAP). Вы можете легко вызывать процедуры XML-RPC как методы Zend_XmlRpc_Client. Задавайте полный адрес сервиса в конструкторе Zend_XmlRpc_Client.

Пример 18.1. Основной запрос XML-RPC

<?php

/**
 * Соединение с сервером framework.zend.com server и вывод массива
 * доступных методов.
 */
require_once 'Zend/XmlRpc/Client.php';

$server = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');

print_r( $server->system->listMethods() );

?>
            

[Замечание] Замечание
Zend_XmlRpc_Client пытается сделать удаленные методы по возможности похожими на "родные" методы. Если удаленный метод содержит пространства имен, как, например, system.listMethods(), то вызов осуществляется с использованием "цепочки объектов" в PHP: $server->system->listMethods().

18.2.2. Использование параметров

Некоторые процедуры сервиса XML-RPC требуют передачи параметров. Необходимые параметры передаются как параметры метода Zend_XmlRpc_Client. Параметры процедуры XML-RPC должны иметь специальный тип XML-RPC. Параметры могут передаваться 2 способами: как "родные" для PHP или как объекты Zend_XmlRpc_Value, которые представляют типы XML-RPC.

18.2.2.1. Передача переменных PHP как параметров

Параметры, передаваемые как переменные PHP, могут быть строками, целыми числами, числами с плавающей точкой, булевыми значениями, массивами или объектами. В этом случае "родной" тип PHP будет автоматически определен и преобразован в один из типов XML-RPC в соответствии с таблицей ниже:

Таблица 18.1. Преобразование типов PHP и XML-RPC

Тип PHP Тип XML-RPC
integer int
double double
boolean boolean
string string
array array
associative array struct
object array
<?php
/** Этой процедуре передается 2 параметра:
 *  - Первый параметр является строкой, которая будет автоматически преобразована в строку XML-RPC
 *  - Второй параметр -- ассоциативный массив, кторорый будет преобразован в структуру XML-RPC 
 */

$p1 = 'parameter 1';
$p2 = array('name' => 'Joe', 'age' => 30);

$service->serviceProcedure($p1, $p2);
?>
            

18.2.2.2. Передача объектов Zend_XmlRpc_Value в качестве параметров

Параметры передаются как объекты Zend_XmlRpc_Value. Вы можете создавать один из экземпляров Zend_XmlRpc_Value для указания точного типа XML-RPC ваших параметров. Основными причинами для точного задания типов XML-RPC являются случаи:

  • Когда вы хотите быть уверенными в том, что процедуре передается корректный тип параметра (т.е. процедура требует целочисленное значение, а вы можете получаете параметр из массива $_GET в виде строки)
  • Когда процедура требует тип base64 или dateTime.iso8601 (которых нет среди "родных" типов PHP)
  • Когда автоматическое преобразование может работать неправильно (например, вы хотите передать пустую структуру XML-RPC как параметр. Пустая структура представляется в PHP пустым массивом, но когда вы передаете пустой массив как параметр, он будет преобразован в массив XML-RPC, так как не является ассоциативным массивом)

Есть два способа создать объект Zend_XmlRpc_Value: явный способ (вызов конструктора объекта) и использование статической функции Zend_XmlRpc_Value::getXmlRpcValue() с константой, обозначающей требуемый тип XML-RPC.

Таблица 18.2. Представление типов XML-RPC объектами Zend_XmlRpc_Value

Тип XML-RPC Соответствующая константа Zend_XmlRpc_Value Объект Zend_XmlRpc_Value
int Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER Zend_XmlRpc_Value_Integer
double Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE Zend_XmlRpc_Value_Double
boolean Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN Zend_XmlRpc_Value_Boolean
string Zend_XmlRpc_Value::XMLRPC_TYPE_STRING Zend_XmlRpc_Value_String
base64 Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64 Zend_XmlRpc_Value_Base64
dateTime.iso8601 Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME Zend_XmlRpc_Value_DateTime
array Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY Zend_XmlRpc_Value_Array
struct Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT Zend_XmlRpc_Value_Struct
<?php
            
/** Процедуре передается 2 параметра:
 *  - Первый параметр имеет тип XML-RPC base64, который создается с помощью
 *  статической функции Zend_XmlRpc_Value::getXmlRpcValue().
 *  - Второй параметр является структурой XML-RPC, которая создается явно.
 */

$p1 = Zend_XmlRpc_Value::getXmlRpcValue('encoded string', Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64);
$p2 = new Zend_XmlRpc_Value_Struct(array('name' => 'Joe', 'age' => 30));

$service->serviceProcedure($p1, $p2);

?>
            

[Замечание] Замечание
Значения параметров по-прежнему даются в виде переменных PHP, но они будут преобразованы в указанный тип с использованием преобразований средствами PHP (т.е. если строка дана как значение для объекта Zend_XmlRpc_Value_Integer, то она будет преобразована с помощью (int)$value).

18.2.2.3. Преобразование строки XML в параметры XML-RPC

Этот метод передачи параметров используется внутри пакета Zend_XmlRpc и не рекомендуется для использования.

Если вам все равно нужен этот метод, то вы должны использовать статическую функцию Zend_XmlRpc_Value::getXmlRpcValue() для разбора строки XML в объект Zend_XmlRpc_Value, который представляет собой надлежащий тип XML-RPC. Функция Zend_XmlRpc_Value::getXmlRpcValue() должна получать 2 параметра: строку XML и константу Zend_XmlRpc_Value::XML_STRING.

18.2.3. Приведение типов параметров

Основное различие между XML-RPC и веб-сервисами SOAP заключается в файле WSDL. Протокол SOAP обычно имеет файл WSDL, который описывает интерфейс веб-сервиса. По этому интерфейсу клиент SOAP знает, параметры каких типов он должен отправить серверу и типы возвращаемых значений. Без файла WSDL могут быть проблемы с узнаванием этих типов.

Решение протокола XML-RPC заключается в использовании специальной процедуры сервиса, называемой system.methodSignature. Эта процедура получает имя процедуры в качестве параметра и возвращает сигнатуру данной процедуры. Сигнатурой является типы необходимых параметров и тип возвращаемого значения.

[Замечание] Замечание
Не все сервера XML-RPC поддерживают специальную процедуру system.methodSignature, сервера, которые не поддерживают ее, не могут поддерживать и приведение типов.

Zend_XmlRpc_Client реализует что-то вроде файлов типа 'WSDL' для серверов XML-RPC, используя процедуру system.methodSignature. По требованию Zend_XmlRpc_Client будет запрашивать список всех процедур сервера XML-RPC, все сигнатуры этих процедур и сохранять все эти данные в файле XML (подобие файла SOAP WSDL). Когда опять используется тот же сервер XML-RPC, пользователь может предоставить этот файл XML и Zend_XmlRpc_Client произведет приведение типов всех параметров для запрошенных процедур в соответствии с их сигнатурами.

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

Пример 18.2. Вызов сервиса XML-RPC с приведением типов

<?php

/**
 * Соединение с сервером XML-RPC и сохранение его сигнатур в файле
 * (эквивалент файлу SOAP WSDL, предоставляемый XML-RPC)
 */
require_once 'Zend/XmlRpc/Client.php';

$service = new Zend_XmlRpc_Client('http://www.example.org/xmlrpc');

file_put_contents('/tmp/xmlrpc-signatures/example.xml', $service->__getMethodsXml());

/* Объект $service содержит все сигнатуры сервера XML-RPC,
    когда вызывается serviceProcedure, его параметр ($param) преобразуется
    к нужному типу в соответствии с сигнатурой процедуры.
 */
$service->serviceProcedure($param);

?>
            
<?php

/**
 * Соединение с сервером XML-RPC с использованием существующего файла сигнатур,
 * удостоверяемся, что типы параметров, передаваемых процедурам, имеют необходимый тип.
 */
require_once 'Zend/XmlRpc/Client.php';

$signature_file_xml = file_get_contents('/tmp/xmlrpc-signatures/example.xml');
$service = new Zend_XmlRpc_Client('http://www.example.org/xmlrpc', 'namespace', $signature_file_xml);

/* Объект $service содержит все сигнатуры сервера XML-RPC,
    когда вызывается serviceProcedure, его параметр($param) преобразуется
    к нужному типу в соответствии с сигнатурой процедуры.
 */
$service->serviceProcedure($param);

?>
            

18.2.4. Получение ответа

Процедура XML-RPC возвращает значение, имеющее тип XML-RPC. Метод Zend_XmlRpc_Client, который вызывает процедуру XML-RPC, возвращает "родной" тип PHP, который преобразуется из возвращенного типа XML-RPC.

Вы можете использовать функцию Zend_XmlRpc_Client::__getResponse(), чтобы получить значение, возвращенное запрошенной процедурой. Функция __getResponse() получает параметр, который показывает тип возвращаемого значения. Опции ответа:

  • Zend_XmlRpc_Client::RESPONSE_PHP_NATIVE - Вернуть возвращаемое значение процедуры как "родной" тип PHP (преобразовать тип XML-RPC в тип PHP).
  • Zend_XmlRpc_Client::RESPONSE_XML_STRING - Вернуть строку XML, представляющую ответ XML-RPC.
  • Zend_XmlRpc_Client::RESPONSE_ZXMLRPC_OBJECT - Вернуть объект Zend_XmlRpc_Value, который представляет возвращенный тип XML-RPC.

<?php

$service->serviceProcedure();

$response = $service->__getResponse();
// $response является переменной PHP, преобразованной из возвращенного значения,
// имеющего тип XML-RPC
  
$response = $service->__getResponse(Zend_XmlRpc_Client::RESPONSE_XML_STRING);
// $response является строкой, содержащей возвращеное процедурой значение
// в представлении XML

$response = $service->__getResponse(Zend_XmlRpc_Client::RESPONSE_ZXMLRPC_OBJECT);
// $response является экземпляром Zend_XmlRpc_Value, представляющим возвращенный
// тип XML-RPC

?>