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] 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] 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] 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
...