1 <sect1 id="zend.xmlrpc.client">
2 <title>Zend_XmlRpc_Client</title>
4 <sect2 id="zend.xmlrpc.client.introduction">
5 <title>Wprowadzenie</title>
8 Zend Framework zapewnia obsługę wywoływania zdalnych serwisów
9 XML-RPC jako klient w pakiecie <code>Zend_XmlRpc_Client</code>.
10 Do głównych funkcjonalności należą: automatyczna konwersja
11 typów pomiędzy PHP a XML-RPC, obiekt serwera proxy oraz dostęp
12 do możliwości introspekcji serwerów.
18 <sect2 id="zend.xmlrpc.client.method-calls">
19 <title>Wywołania metod</title>
22 Konstruktor klasy <code>Zend_XmlRpc_Client</code> odbiera w
23 pierwszym parametrze adres URL zdalnego serwera XML-RPC. Nowa
24 zwrócona instancja może być użyta do wywołania dowolnej ilości
25 zdalnych metod tego serwera.
29 Aby wywołać zdalną metodę za pomocą klienta XML-RPC, utwórz
30 instancję i użyj metody <code>call()</code>. Przykładowy kod poniżej
31 używa demonstracyjnego serwera XML-RPC na stronie Zend Framework.
32 Możesz go użyć do testowania lub eksplorowania komponentów
33 <code>Zend_XmlRpc</code>.
36 <example id="zend.xmlrpc.client.method-calls.example-1">
37 <title>Wywołanie metody XML-RPC</title>
38 <programlisting role="php"><![CDATA[
39 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
41 echo $client->call('test.sayHello');
49 Wartość XML-RPC zwracana przez wywołanie zdalnej metody jest
50 automatycznie konwertowana do odpowiedniego natywnego typu
51 PHP. W powyższym przykładzie, zwraca jest wartość typu
52 <code>string</code> i jest ona natychmiast gotowa do użycia.
56 Pierwszy parametr metody <code>call()</code> to nazwa zdalnej metody
57 do wywołania. Jeśli zdalna metoda wymaga jakichkolwiek parametrów,
58 mogą być one wysłane przez podanie do metody <code>call()</code>
59 drugiego opcjonalnego parametru w postaci tablicy wartości do
60 przekazania do zdalnej metody:
63 <example id="zend.xmlrpc.client.method-calls.example-2">
64 <title>Wywołanie metody XML-RPC z parametrem</title>
65 <programlisting role="php"><![CDATA[
66 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
71 $result = $client->call('test.sayHello', array($arg1, $arg2));
73 // zmienna $result jest natywnego typu PHP
79 Jeśli zdalna metoda nie wymaga parametrów, ten opcjonalony parametr
80 może pozostać pusty, lub może być pustą tablicą
81 <code>array()</code>. Tablica parametrów dla zdalnej metody może
82 zawierać natywne typy PHP, obiekty <code>Zend_XmlRpc_Value</code>,
87 Metoda <code>call()</code> automatycznie skonwertuje odpowiedź
88 XML-RPC i zwróci wartość odpowiedniego natywnego typu PHP. Obiekt
89 <code>Zend_XmlRpc_Response</code> ze zwróconą wartością będzie także
90 dostępny po wywołaniu poprzez wywołanie metody
91 <code>getLastResponse()</code>.
95 <sect2 id="zend.xmlrpc.value.parameters">
96 <title>Typy i konwersje</title>
98 Niektóre zdalne wywołania metod wymagają parametrów. Są one
99 przekazywane do metody <code>call()</code> obiektu
100 <code>Zend_XmlRpc_Client</code> jako tablica w drugim parametrze.
101 Każdy podany parametr może być natywnego typu PHP, wtedy będzie
102 automatycznie skonwertowany, lub może być obiektem reprezentującym
103 specyficzny typ XML-RPC (jeden z obiektów <code>Zend_XmlRpc_Value</code>).
106 <sect3 id="zend.xmlrpc.value.parameters.php-native">
107 <title>Natywne typy PHP jako parametry</title>
109 Parametry mogą być przekazane do metody <code>call()</code> jako
110 natywne zmienne PHP, czyli jako <code>string</code>,
111 <code>integer</code>, <code>float</code>, <code>boolean</code>,
112 <code>array</code>, lub <code>object</code>. W tym przypadku
113 każda natywna wartość zostanie automatycznie wykryta i
114 skonwertowana do jednego z typów XML-RPC, zgodnie z tą tabelą:
117 <table id="zend.xmlrpc.value.parameters.php-native.table-1">
118 <title>Konwersje między typami PHP oraz XML-RPC</title>
122 <entry>Natywny typ PHP</entry>
123 <entry>Typ XML-RPC</entry>
128 <entry>integer</entry>
132 <entry>double</entry>
133 <entry>double</entry>
136 <entry>boolean</entry>
137 <entry>boolean</entry>
140 <entry>string</entry>
141 <entry>string</entry>
148 <entry>associative array</entry>
149 <entry>struct</entry>
152 <entry>object</entry>
160 <title>Na co zamieniane są puste tablice?</title>
163 Przekazanie pustej tablicy do metody XML-RPC jest
164 problematyczne, ponieważ może ona przedstawiać pustą tablicę
165 lub strukturę. Obiekt <code>Zend_XmlRpc_Client</code>
166 wykrywa takie przypadki i wywołuje metodę serwera
167 <code>system.methodSignature</code> aby określić na jaki typ
168 XML-RPC powinien tę tablicę zamienić
172 Jednak może to powodować pewne problemy. Po pierwsze,
173 serwery które nie obsługują metody
174 <code>system.methodSignature</code> będą zapisywać nieudane
175 żądania, a obiekt <code>Zend_XmlRpc_Client</code> będzie
176 wtedy zamieniał puste tablice na puste tablice XML-RPC.
177 Po drugie oznacza to, że każde wywołanie z argumentami w
178 postaci tablic będą powodować konieczność przeprowadzenia
179 dodatkowego żądania do zdalnego serwera.
183 Aby całkowicie zablokować takie sprawdzanie, możesz
184 wywołać metodę <code>setSkipSystemLookup()</code> przed
185 wywołaniem metody XML-RPC call:
188 <programlisting role="php"><![CDATA[
189 $client->setSkipSystemLookup(true);
190 $result = $client->call('foo.bar', array(array()));
196 <sect3 id="zend.xmlrpc.value.parameters.xmlrpc-value">
197 <title>Obiekty <code>Zend_XmlRpc_Value</code> jako parametry</title>
199 Parametry mogą być także tworzone jako instancje klasy
200 <code>Zend_XmlRpc_Value</code> w celu określenia dokładnego typu
201 XML-RPC. Konieczne jest to gdy:
206 gdy chcesz być pewny, że parametr poprawnego typu
207 jest przekazany do procedury (np. procedura wymaga
208 liczby całkowitej, a ty możesz pobrać tę wartość z
209 bazy jako łańcuch znaków).
214 Wtedy gdy procedura wymaga typu <code>base64</code>
215 lub <code>dateTime.iso8601</code> (które nie istnieją
216 jako natywne typy PHP)
221 Gdy automatyczna konwersja może nie zadziałać (np.
222 gdy chcesz przekazać pustą strukturę XML-RPC jako
223 parametr. Puste struktury są reprezentowane przez
224 puste tablice w PHP, ale jeśli podasz pustą tablicę
225 w parametrze będzie ona automatycznie skonwertowana
226 do tablicy XML-RPC z tego powodu, że nie jest ona
234 Są dwa sposoby utworzenia obiektu <code>Zend_XmlRpc_Value</code>:
235 bezpośrednie utworzenie instancji jednej z podklas klasy
236 <code>Zend_XmlRpc_Value</code>,lub użycie statycznej metody
237 fabryki <code>Zend_XmlRpc_Value::getXmlRpcValue()</code>.
240 <table id="zend.xmlrpc.value.parameters.xmlrpc-value.table-1">
241 <title>Obiekty <code>Zend_XmlRpc_Value</code> dla typów XML-RPC</title>
245 <entry>Typ XML-RPC</entry>
246 <entry>Stała <code>Zend_XmlRpc_Value</code></entry>
247 <entry>Obiekt <code>Zend_XmlRpc_Value</code> Object</entry>
253 <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER</code></entry>
254 <entry><code>Zend_XmlRpc_Value_Integer</code></entry>
257 <entry>double</entry>
258 <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE</code></entry>
259 <entry><code>Zend_XmlRpc_Value_Double</code></entry>
262 <entry>boolean</entry>
263 <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN</code></entry>
264 <entry><code>Zend_XmlRpc_Value_Boolean</code></entry>
267 <entry>string</entry>
268 <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_STRING</code></entry>
269 <entry><code>Zend_XmlRpc_Value_String</code></entry>
272 <entry>base64</entry>
273 <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64</code></entry>
274 <entry><code>Zend_XmlRpc_Value_Base64</code></entry>
277 <entry>dateTime.iso8601</entry>
278 <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME</code></entry>
279 <entry><code>Zend_XmlRpc_Value_DateTime</code></entry>
283 <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY</code></entry>
284 <entry><code>Zend_XmlRpc_Value_Array</code></entry>
287 <entry>struct</entry>
288 <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT</code></entry>
289 <entry><code>Zend_XmlRpc_Value_Struct</code></entry>
297 <title>Automatyczna konwersja</title>
299 Kiedy tworzymy nowy obiekt
300 <code>Zend_XmlRpc_Value</code>, jego wartość jest
301 ustawiana jako typ PHP. Wartość będzie konwertowana do
302 określonego typu używając rzytowania typów PHP. Na
303 przykład, jeśli podany jest łańcuch znaków jako wartość
304 do obiektu <code>Zend_XmlRpc_Value_Integer</code>,
305 wartość ta będzie konwertowana za pomocą
306 <code>(int)$value</code>.
313 <sect2 id="zend.xmlrpc.client.requests-and-responses">
314 <title>Obiekt serwera proxy</title>
316 Innym sposobem wywołania zdalnych metod za pomocą klienta XML-RPC
317 jest użycie serwera proxy. Jest to obiekt PHP, który rozszerza
318 zdalną przestrzeń nazw XML-RPC, powodując, że obiekt ten działa jak
323 Aby utworzyć instancję serwera proxy, wywołaj metodę
324 <code>getProxy()</code> instancji <code>Zend_XmlRpc_Client</code>.
325 To zwróci instancję obiektu <code>Zend_XmlRpc_Client_ServerProxy</code>.
326 Wywołanie dowolnej metody na obiekcie serwera proxy będzie przekazane
327 do zdalnego serwera, a parametry będą przekazane jak do każdej innej
331 <example id="zend.xmlrpc.client.requests-and-responses.example-1">
332 <title>Rozszerzanie domyślnej przestrzeni nazw</title>
333 <programlisting role="php"><![CDATA[
334 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
336 $server = $client->getProxy(); // Rozszerza domyślną przestrzeń nazw
338 $hello = $server->test->sayHello(1, 2); // test.Hello(1, 2) zwraca "hello"
344 Metoda <code>getProxy()</code> pobiera opcjonalny argument
345 określający, która przestrzeń nazw zdalnego serwera chcemy
346 rozszerzyć. Jeśli przestrzeń nazwa nie zostanie określona,
347 rozszerzona zostanie domyślna przestrzeń nazwa. W następnym
348 przykładzie będzie rozszerzona przestrzeń nazw
352 <example id="zend.xmlrpc.client.requests-and-responses.example-2">
353 <title>Rozszerzanie dowolnej przestrzeni nazw</title>
354 <programlisting role="php"><![CDATA[
355 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
357 $test = $client->getProxy('test'); // Rozszerza przestrzeń nazwa "test"
359 $hello = $test->sayHello(1, 2); // test.Hello(1,2) zwraca "hello"
365 Jeśli zdalny serwer obsługuje zagnieżdżone przestrzenie nazwa o
366 dowolnej ilości zagnieżdżeń, mogą być one także użyte przez serwer
367 proxy. Na przykład, jeśli serwer w powyższym przykładzie posiada
368 metodę <code>test.foo.bar()</code>, może być ona wywołana jako
369 <code>$test->foo->bar()</code>.
374 <sect2 id="zend.xmlrpc.client.error-handling">
375 <title>Obsługa błędów</title>
377 Dwa rodzaje błędów mogą wystąpić podczas wywoływania metod XML-RPC:
378 błędy HTTP oraz błędy XML-RPC. Klient <code>Zend_XmlRpc_Client</code>
379 rozpoznaje te błędy i daje możliwośc wykrycia i złapania każdego z
383 <sect3 id="zend.xmlrpc.client.error-handling.http">
384 <title>Błędy HTTP</title>
387 Jeśli wystąpi jakiś błąd HTTP, na przykład gdy zdalny serwer
388 HTTP zwróci błąd <code>404 Not Found</code>, wyrzucony zostanie
389 wyjątek <code>Zend_XmlRpc_Client_HttpException</code>.
392 <example id="zend.xmlrpc.client.error-handling.http.example-1">
393 <title>Obsługa błędów HTTP</title>
395 <programlisting role="php"><![CDATA[
396 $client = new Zend_XmlRpc_Client('http://foo/404');
400 $client->call('bar', array($arg1, $arg2));
402 } catch (Zend_XmlRpc_Client_HttpException $e) {
404 // $e->getCode() zwraca 404
405 // $e->getMessage() zwraca "Not found"
413 Zależnie od tego jak używany jest klient XML-RPC, gdy wystąpi
414 błąd HTTP zostanie wyrzucony wyjątek
415 <code>Zend_XmlRpc_Client_HttpException</code>.
419 <sect3 id="zend.xmlrpc.client.error-handling.faults">
420 <title>Błędy XML-RPC</title>
423 Błędy XML-RPC są analogiczne do wyjątków PHP. Jest to specjalny
424 typ zwracany przez wywołanie metody XML-RPC, który zawiera
425 zarówno kod błędu jak i informacje o błędzie. Błędy XML-RPC są
426 obsługiwane różnie, zależnie od kontekstu w jakim użyty jest
427 obiekt <code>Zend_XmlRpc_Client</code>.
431 Gdy użyta jest metoda <code>call()</code> lub obiekt serwera
432 proxy, błędy XML-RPC spowodują wyrzucenie wyjątku
433 <code>Zend_XmlRpc_Client_FaultException</code>. Kod oraz
434 informacje o błędzie wyjątku będą bezpośrednio mapować do
435 ich odpowiednich wartości oryginalnej odpowiedzi błędu XML-RPC.
438 <example id="zend.xmlrpc.client.error-handling.faults.example-1">
439 <title>Obsługa błędów XML-RPC</title>
441 <programlisting role="php"><![CDATA[
442 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
446 $client->call('badMethod');
448 } catch (Zend_XmlRpc_Client_FaultException $e) {
450 // $e->getCode() zwraca 1
451 // $e->getMessage() zwraca "Unknown method"
459 Gdy metoda <code>call()</code> jest użyta do przeprowadzenia
460 żądania, przy wystąpieniu błędu zostanie wyrzucony wyjątek
461 <code>Zend_XmlRpc_Client_FaultException</code>. Obiekt
462 <code>Zend_XmlRpc_Response</code> zawierający błąd będzie także
463 dostępny przez wywołanie metody <code>getLastResponse()</code>.
467 Gdy do przeprowadzenia żądania użyta jest metoda
468 <code>doRequest()</code>, nie będzie wyrzucony żaden wyjątek.
469 Zamiast tego zwrócony zostanie obiekt
470 <code>Zend_XmlRpc_Response</code> zawierający informacje o
471 błędzie. Może to być sprawdzone za pomocą metody
472 <code>isFault()</code> obiektu <code>Zend_XmlRpc_Response</code>.
478 <sect2 id="zend.xmlrpc.client.introspection">
479 <title>Introspekcja serwerów</title>
481 Niektóre serwery XML-RPC obsługują metody introspekcji w przestrzeni
482 nazw XML-RPC <code>system.</code>. <code>Zend_XmlRpc_Client</code>
483 zapewnia specjalną obsługę dla serwerów z taką funkcjonalnością.
487 Instancja <code>Zend_XmlRpc_Client_ServerIntrospection</code> może
488 być odebrana przez wywołanie metody <code>getIntrospector()</code>
489 obiektu <code>Zend_XmlRpcClient</code>. Następnie obiekt ten może
490 być użyty do przeprowadzenia operacji introspekcji na serwerze.
494 <sect2 id="zend.xmlrpc.client.request-to-response">
495 <title>Od żądania do odpowiedzi</title>
497 Wewnątrz wygląda to tak, że metoda <code>call()</code> instancji
498 obiektu <code>Zend_XmlRpc_Client</code> buduje obiekt żądania
499 (<code>Zend_XmlRpc_Request</code>) i wysyła go do innej metody,
500 <code>doRequest()</code>, ktora zwraca obiekt odpowiedzi
501 (<code>Zend_XmlRpc_Response</code>).
505 Metoda <code>doRequest()</code> jest także dostępna dla
506 bezpośredniego użycia:
509 <example id="zend.xmlrpc.client.request-to-response.example-1">
510 <title>Przetwarzanie żądania do odpowiedzi</title>
512 <programlisting role="php"><![CDATA[
513 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
515 $request = new Zend_XmlRpc_Request();
516 $request->setMethod('test.sayHello');
517 $request->setParams(array('foo', 'bar'));
519 $client->doRequest($request);
521 // $server->getLastRequest() zwraca instancję Zend_XmlRpc_Request
522 // $server->getLastResponse() zwraca instancję Zend_XmlRpc_Response
528 Zawsze po wywołaniu metody XML-RPC przez klienta, niezależnie od
529 tego czy za pomocą metody <code>call()</code>, metody
530 <code>doRequest()</code> czy poprzez serwer proxy, ostatni obiekt
531 żądania i odpowiadający mu obiekt odpowiedzi będą zawsze dostępne
532 odpowiednio za pomocą metod <code>getLastRequest()</code> oraz
533 <code>getLastResponse()</code>.
537 <sect2 id="zend.xmlrpc.client.http-client">
538 <title>Klient HTTP i testowanie</title>
541 We wszystkich poprzednich przykładach nie został określony żaden
542 klient HTTP. W takim wypadku utworzona zostaje nowa instancja
543 <code>Zend_Http_Client</code> z jej domyślnymi opcjami i ta
544 instancja zostaje użyta automatycznie przez
545 <code>Zend_XmlRpc_Client</code>.
549 Klient HTTP może być odebrany w dowolnej chwili za pomocą metody
550 <code>getHttpClient()</code>. W większości przypadków domyślny
551 klient HTTP będzie wystarczający. Jakkolwiek, metoda
552 <code>setHttpClient()</code> pozwala na ustawienie innego klienta
553 HTTP dla danej instancji.
557 Metoda <code>setHttpClient()</code> jest szczególnie przydatna dla
558 testów jednostkowych. Gdy jest połączona z obiektem
559 <code>Zend_Http_Client_Adapter_Test</code>, zdalne serwisy mogą
560 być zasymulowane dla naszego testowania. Zobacz testy jednostkowe
561 dla <code>Zend_XmlRpc_Client</code> aby zobaczyć jak można to