17.2. Zend_XmlRpc_Client
Poprzedni | Rozdział 17. Zend_XmlRpc | Następny

## 17.2. Zend_XmlRpc_Client

### 17.2.1. Wprowadzenie

Użycie klienta `Zend_XmlRpc_Client` jest bardzo podobne do użycia obiektów `SoapClient` (rozszerzenie SOAP). Możesz w prosty sposób wywołać procedury XML-RPC jako metody obiektu `Zend_XmlRpc_Client`. Pełny adres serwisu możesz określić w konstruktorze `Zend_XmlRpc_Client`.

Przykład 17.1. Proste zapytanie XML-RPC

    <?php
    /**
     * Łączy się  z serwerem framework.zend.com i pobiera
     * tablicę z dostępnymi metodami.
     */
    require_once 'Zend/XmlRpc/Client.php';

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

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

    ?>

| Notatka
`Zend_XmlRpc_Client` dąży do tego, aby użycie zdalnych metod były tak podobne do metod natywnych jak to tylko możliwe. Jeśli zdalne metody zawierają przestrzenie nazw jak np. `system.listMethods()`, powinny one być wywoływane w PHP w sposób łańcuchowy: `$server->system->listMethods()`.

### 17.2.2. Użycie parametrów

Niektóre procedury serwisów XML-RPC wymagają parametrów, potrzebne parametry są przekazywae jako parametry do metody `Zend_XmlRpc_Client`. Parametry procedur XML-RPC muszą mieć określony typ XML-RPC. Parametry mogą być przekazane na dwa sposoby: jako natywna zmienna PHP lub jako obiekt `Zend_XmlRpc_Value` reprezentujący wartość typu XML-RPC.

#### 17.2.2.1. Przekazywanie natywnych wartości PHP jako parametrów

Parametery są przekazywane jako natywne zmienne PHP, czyli łańcuch znaków (string), liczba całkowita (integer), liczba zmiennoprzecinkowa (float), wartość logiczna (boolean), tablica (array) lub obiekt (object). W tym przypadku każda natywna wartość PHP zostanie automatycznie wykryta i skonwertowana do typu XML-RPC zgodnie z tą tabelą:

Tabela 17.1. Konwersja natywnych wartości PHP do typów XML-RPC

Natywny typ PHP | Typ XML-RPC
--- | ---
integer | int
double | double
boolean | boolean
string | string
array | array
associative array | struct
object | array

    ...
    /** 2 parametry są przekazywane w tej procedurze
     *  Pierwszy parametr jest łańcuchem znaków więc zostanie skonwertowany do łańcucha znaków XML-RPC
     *  Drugi parametr jest tablicą asocjacyjną i będzie skonwertowany do struktury XML-RPC
     */

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

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

#### 17.2.2.2. Przekazywanie obiektów `Zend_XmlRpc_Value` jako parametrów

Parametry są przekazywane jako obiekty `Zend_XmlRpc_Value`. Możesz utworzyć jedną z instancji `Zend_XmlRpc_Value` aby określić dokładny typ XML-RPC parametrów. Głównymi powodami dokładnego określania typów XML-RPC są:

- Gdy chcesz być pewny, że parametr poprawnego typu jest przekazywany do procedury (np. gdy procedura wymaga parametru typu integer a ty możesz otrzymać parametr z tablicy $_GET, który jest łańcuchem znaków)
- Gdy procedura wymaga typu base64 lub dateTime, typu iso8601 (który nie istnieje jako natywny typ PHP)
- Gdy automatyczna konwersja zawiedzie (np. gdy chcesz przekazać pustą strukturę XML-RPC jako parametr. Puste struktury są reprezentowane jako puste tablice w PHP, ale gdy w parametrze przekażesz pustą tablicę to będzie ona automatycznie skonwertowana do tablicy XML-RPC ponieważ nie jest ona tablicą asocjacyjną.)

Są dwa sposoby utworzenia obiektu `Zend_XmlRpc_Value`: sposób ścisły (wywołanie konstruktora obiektu) lub użycie statycznej funkcji `Zend_XmlRpc_Value::getXmlRpcValue()` z wymaganą stałą XML-RPC.

Tabela 17.2. Obiekt `Zend_XmlRpc_Value` reprezentujący typy XML-RPC

Typ XML-RPC | Odpowiadająca stała `Zend_XmlRpc_Value` | Obiekt `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`

    ...
    /** 2 parametry przekazane do procedury
     *  Pierwszy parametr jest typu base64 XML-RPC  i jest tworzony przy użyciu statycznej metody Zend_XmlRpc_Value::getXmlRpcValue()
     *  Drugi parametr jest strukturą XML-RPC i jest tworzony bezpośrednio za pomocą konstruktora
     */

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

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

| Notatka
Wartość parametru jest także podana jako zmienna PHP, ale jest ona konwertowana do określonego typu przy użyciu technik konwersji (np. jeśli łańcuch znaków zostanie przekazany do obiektu `Zend_XmlRpc_Value_Integer`, to będzie on skonwertowany przy użyciu `(int)$value`).

#### 17.2.2.3. Konwersja danych XML do parametrów XML-RPC

Ta metoda przekazywania parametrów jest używana wewnętrznie w pakiecie `Zend_XmlRpc` i nie jest polecana.

Jeśli wciąż potrzebujesz użyć tej metody, powinieneś użyć statycznej funkcji `Zend_XmlRpc_Value::getXmlRpcValue()` aby przeprowadzić konwersję łańcucha znaków XML do obiektu `Zend_XmlRpc_Value`, który reprezentuje odpowiedni typ XML-RPC. Funkcja `Zend_XmlRpc_Value::getXmlRpcValue()` powinna otrzymać 2 parametry: łańcuch znaków XML i stałą `Zend_XmlRpc_Value::XML_STRING`.

### 17.2.3. Informacje o parametrach

Główną różnicą między XML-RPC a serwisami SOAP jest plik WSDL. Protokół SOAP zazwyczaj ma plik WSDL który opisuje interfejs serwisu. Zależnie od tego interfejsu, klient SOAP wie jakiego typu parametry musi wysłać do serwera i jaki jest typ zwracanej wartości. Bez pliku WSDL użytkownik mógłby mieć problem ze zidentyfikowaniem tych typów.

Protokół XML-RPC używa specjalnej procedury zwanej `system.methodSignature`. Ta procedura przekazuje w jako parametr nazwę procedury i zwraca sygnaturę tej procedury. Sygnatura informuje o wymaganych typach parametrów i o typie zwracanej przez nią wartości.

| Notatka
Nie wszystkie serwery XML-RPC obsługują procedurę `system.methodSignature`, serwery które jej nie obsługują, nie umożliwiają identyfikowania typów parametrów.

Klient `Zend_XmlRpc_Client` implementuje plik rodzaju 'WSDL' dla serwerów XML-RPC przy użyciu procedury `system.methodSignature`. Jeśli zostanie ona wywołana, klient `Zend_XmlRpc_Client` zażąda listy wszystkich procedur serwera XML-RPC, następnie zażąda sygnatur wszystkich tych procedur, i zatrzyma te dane w pliku XML (podobnym do pliku SOAP WSDL). Gdy użyjemy tego samego serwera XML-RPC ponownie, użytkownik może dostarczyć plik XML i wtedy `Zend_XmlRpc_Client` skonwertuje wszystkie parametry dla wywołanych procedur według ich sygnatur.

Plik XML z sygnaturami tworzony jest przez wywołanie funkcji `Zend_XmlRpc_Client::__getMethodsXml()` (funkcja zwraca łańcuch znaków XML zawierający wszystkie sygnatury). Aby wybrać istniejący plik XML z sygnaturami, użytkownik może przekazać dane XML jako parametr do konstruktora `Zend_XmlRpc_Client` lub wywołać metodę `Zend_XmlRpc_Client::__setMethodsXml()`.

Przykład 17.2. Wywołanie serwisu XML-RPC z użyciem pliku sygnatur

    <?php
    /**
     * Łączy się z serwerem XML-RPC i zapisuje jego plik z sygnaturami (odpowiednik XML-RPC pliku SOAP WSDL)
     */
    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());

    /* Obiekt $service zawiera wszystkie sygnatury serwera XML-RPC, teraz
       gdy wywołana jest procedura serviceProcedure, jej parametr ($param) jest
       konwertowany do odpowiedniego typu według sygnatury.
     */
    $service->serviceProcedure($param);
    ?>

    <?php
    /**
     * Łączy się z serwerem XML-RPC przy użyciu istniejącego pliku sygnatury, mamy pewność,
     * że typy parametrów przekazane do procedur są odpowiednie.
     */
    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);

    /* Obiekt $service zawiera wszystkie sygnatury serwera XML-RPC, teraz
       gdy wywołana jest procedura serviceProcedure, jej parametr ($param) jest
       konwertowany do odpowiedniego typu według sygnatury.
     */
    $service->serviceProcedure($param);
    ?>

### 17.2.4. Uzyskiwanie odpowiedzi

Procedura XML-RPC zwraca wartość typu XML-RPC. Metoda `Zend_XmlRpc_Client` która wywołuje procedurę XML-RPC zwraca wartość natywnego typu PHP, która jest skonwertowana ze zwróconego typu XML-RPC.

Możesz użyć funkcji `Zend_XmlRpc_Client::__getResponse()` aby otrzymać zwróconą wartość wywołanej procedury. Funkcja `__getResponse()` przyjmuje parametr, który mówi jakiego typu wartość ma zwrócić. Opcje odpowiedzi:

- `Zend_XmlRpc_Client::RESPONSE_PHP_NATIVE` - Zwraca wartość jako natywną wartość PHP (konwertuje typ XML-RPC do typu PHP).
- `Zend_XmlRpc_Client::RESPONSE_XML_STRING` - Zwraca odpowiedź serwisu XML-RPC w postaci łańcucha znaków XML.
- `Zend_XmlRpc_Client::RESPONSE_ZXMLRPC_OBJECT` - Zwraca obiekt `Zend_XmlRpc_Value` który reprezentuje zwrócony typ XML-RPC.

    ...
    $service->serviceProcedure();

    $response = $service->__getResponse();
    // $response jest zmienną PHP skonwertowaną ze zwróconej wartości XML-RPC

    $response = $service->__getResponse(ZXmlRpcClient::RESPONSE_XML_STRING);
    // $response jest zmienną zawierającą łańcuch znaków XML reprezentującą zwróconą wartość

    $response = $service->__getResponse(ZXmlRpcClient::RESPONSE_ZXMLRPC_OBJECT);
    // $response jest instancją obiektu Zend_XmlRpc_Value reprezentującą zwróconą wartość XML-RPC
    ...

Poprzedni | Początek rozdziału | Następny
Rozdział 17. Zend_XmlRpc | Spis treści | Dodatek A. Zend Framework PHP Coding Standard