18.2. Zend_XmlRpc_Client
Пред. | Глава 18. Zend_XmlRpc | След.

## 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

    ?>

Пред. | Уровень выше | След.
Глава 18. Zend_XmlRpc | Начало | Приложение A. Стандарт кодирования на PHP в Zend Framework'е