File: Zend_XmlRpc_Server.xml

package info (click to toggle)
zendframework 1.12.9%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 133,584 kB
  • sloc: xml: 1,311,829; php: 570,173; sh: 170; makefile: 125; sql: 121
file content (495 lines) | stat: -rw-r--r-- 19,100 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
<sect1 id="zend.xmlrpc.server">
    <title>Zend_XmlRpc_Server</title>

    <sect2 id="zend.xmlrpc.server.introduction">
        <title>Wprowadzenie</title>

        <para>Klasa Zend_XmlRpc_Server jest przeznaczona do użycia jako
            pełnofunkcjonalny serwer XML-RPC, zgodny ze
            <ulink url="http://www.xmlrpc.com/spec">specyfikacją przedstawioną
            na www.xmlrpc.com</ulink>. Dodatkowo implementuje ona metodę
            system.multicall(), pozwalającą na wywołanie wielu metod podczas
            jednego żądania.
        </para>
    </sect2>

    <sect2 id="zend.xmlrpc.server.usage">
        <title>Podstawowe użycie</title>

        <para>
            Przykład najbardziej podstawowego przypadku użycia:
        </para>

        <programlisting role="php"><![CDATA[
$server = new Zend_XmlRpc_Server();
$server->setClass('My_Service_Class');
echo $server->handle();
]]>
        </programlisting>
    </sect2>

    <sect2 id="zend.xmlrpc.server.structure">
        <title>Struktura serwera</title>

        <para>
            Zend_XmlRpc_Server składa się z wielu różnych komponentów, od
            samego serwera, przez obiekty żądania, obiekty odpowiedzi aż do
            obiektów błędów.
        </para>

        <para>
            Aby uruchomić serwer Zend_XmlRpc_Server, programista musi dołączyć
            jedną lub więcej klas albo funkcji do serwera, za pomocą metod
            <code>setClass()</code> oraz <code>addFunction()</code>.
        </para>

        <para>
            Kiedy jest to już zrobione, możesz przekazać obiekt
            <code>Zend_XmlRpc_Request</code> do metody
            <code>Zend_XmlRpc_Server::handle()</code>, lub zostanie utworzona
            instancja obiektu <code>Zend_XmlRpc_Request_Http</code> w przypadku
            gdy nie zostanie zapewniony żaden obiekt -- spowoduje to pobieranie
            żądań z <code>php://input</code>.
        </para>

        <para>
            <code>Zend_XmlRpc_Server::handle()</code> próbuje wtedy uruchomić
            odpowiednią klasę obsługującą, zależnie od użytej metody dostępu.
            Zwraca wtedy obiekt oparty na <code>Zend_XmlRpc_Response</code> lub
            obiekt <code>Zend_XmlRpc_Server_Fault</code>. Oba te obiekty mają
            dostępne metody <code>__toString()</code>, ktore tworzą poprawne
            odpowiedzi XML-RPC, pozwalając na bezpośrednie ich wyświetlenie.
        </para>
    </sect2>

    <sect2 id="zend.xmlrpc.server.conventions">
        <title>Konwencje</title>
        <para>
            Zend_XmlRpc_Server pozwala programiście dołączać funkcje oraz metody
            klas jako uruchamialne metody XML-RPC. Poprzez Zend_Server_Reflection,
            przeprowadzana jest introspekcja dla wszystkich dołączanych metod,
            używając bloków dokumentacji funkcji i metod do określenia opisów
            pomocy dla metod oraz sygnatur metod.
        </para>

        <para>
            XML-RPC nie mają w typach PHP dokładnych odpowiedników. Jednak skrypt
            spróbuje dopasować najlepszy typ na podstawie wartości znajdujących
            się w polach @param oraz @return. Niektóre typy XML-RPC nie mają
            dokładnych odpowiedników w typach PHP, więc powinny być rzutowane
            używając typów XML-RPC w komentarzach phpdoc. Są to:
        </para>

        <itemizedlist>
            <listitem><para>dateTime.iso8601, łańcuch znaków sformatowany jako
                    YYYYMMDDTHH:mm:ss</para></listitem>
            <listitem><para>base64, dane zakodowane jako base64</para></listitem>
            <listitem><para>struct, dowolna tablica asocjacyjna</para></listitem>
        </itemizedlist>

        <para>
            Przykład wywołania przykładowej funkcji:
        </para>

        <programlisting role="php"><![CDATA[
/**
* To jest przykładowa funkcja
*
* @param base64 $val1 Dane zakodowane jako Base64
* @param dateTime.iso8601 $val2 Data ISO
* @param struct $val3 Tablica asocjacyjna
* @return struct
*/
function myFunc($val1, $val2, $val3)
{
}
]]>
        </programlisting>

        <para>
            PhpDocumentor nie przeprowadza weryfikacji typów określonych dla
            parametrów lub zwracanych wartości, więc nie będzie to miało wpływu
            na twoją dokumentację API
            Providing the hinting is necessary, however, when the
            server is validating the parameters provided to the method call.
        </para>

        <para>
            Poprawne jest określenie wielu typów zarówno dla parametrów jak i
            dla zwracanych wartości; specyfikacja XML-RPC sugeruje nawet, że
            metoda system.methodSignature powinna zwracać tablicę wszystkich
            możliwych sygnatur metody (np. wszystkie możliwe kombinacje
            parametrów i zwracanych wartości). Możesz to zrobić tak jak robisz
            to w PhpDocumentor, używając operatora '|':
        </para>

        <programlisting role="php"><![CDATA[
/**
* To jest przykładowa funkcja
*
* @param string|base64 $val1 Łańcuch znaków lub dane zakodowane jako base64
* @param string|dateTime.iso8601 $val2 Łańcuch znaków lub data ISO
* @param array|struct $val3 Normalnie indeksowana tablica lub tablica asocjacyjna
* @return boolean|struct
*/
function myFunc($val1, $val2, $val3)
{
}
]]>
        </programlisting>

        <para>
            Jedna uwaga: dopuszczanie do utworzenia wielu różnych sygnatur może
            doprowadzić do dezorientacji programistów używających serwisów;
            W zasadzie metoda XML-RPC powinna mieć tylko jedną sygnaturę.
        </para>
    </sect2>

    <sect2 id="zend.xmlrpc.server.namespaces">
        <title>Używanie przestrzeni nazw</title>

        <para>
            XML-RPC posiada system przestrzeni nazw; najprościej mówiąc, pozwala
            to na grupowanie metod XML-RPC w przestrzenie nazw oddzielone
            znakiem kropki. Ułatwia to zapobieganie konfliktom pomiędzy metodami
            pochodzącymi z rożnych klas. Przykładowo, serwer XML-RPC powinien
            udostępniać kilka metod w przestrzeni nazw 'system':
        </para>

        <itemizedlist>
            <listitem><para>system.listMethods</para></listitem>
            <listitem><para>system.methodHelp</para></listitem>
            <listitem><para>system.methodSignature</para></listitem>
        </itemizedlist>

        <para>
            Wewnątrz odpowiada to metodom o tych samych w obiekcie
            Zend_XmlRpc_Server.
        </para>

        <para>
            Jeśli chcesz dodać przestrzenie nazw do metod, które oferujesz, po
            prostu podaj przestrzeń nazw do odpowiedniej metody wtedy, gdy
            dołączasz funkcję lub klasę:
        </para>

        <programlisting role="php"><![CDATA[
// Wszystkie publiczne metody klasy My_Service_Class będą dostępne jako
// myservice.METHODNAME
$server->setClass('My_Service_Class', 'myservice');

// Funkcja 'somefunc' będzie dostępna jako funcs.somefunc
$server->addFunction('somefunc', 'funcs');
]]>
        </programlisting>
    </sect2>

    <sect2 id="zend.xmlrpc.server.request">
        <title>Własny obiekt żądania</title>

        <para>
            W większości przypadków będziesz używał domyślnego obiektu żądania
            dostarczanego przez Zend_XmlRpc_Server, którym jest obiekt
            Zend_XmlRpc_Request_Http. Jednak czasem możesz chcieć aby usługa
            XML-RPC była dostępna przez CLI, GUI lub inne środowisko, lub możesz
            chcieć zapisywać informacje o przychodzących żądaniach. Aby to
            zrobić, możesz utworzyć własny obiekt żądania, który rozszerza
            obiekt Zend_XmlRpc_Request. Najważniejszą rzeczą jest zapamiętanie
            aby zawsze implementować metody getMethod() oraz getParams() co
            pozwoli na to, że serwer XML-RPC będzie mógł pobrać te informacje w
            celu uruchomienia żądania.
        </para>
    </sect2>

    <sect2 id="zend.xmlrpc.server.response">
        <title>Własne odpowiedzi</title>

        <para>
            Podobnie jak obiekty żądania, Zend_XmlRpc_Server może zwracać własne
            obiekty odpowiedzi; domyślnie zwracany jest obiekt
            Zend_XmlRpc_Response_Http, który wysyła odpowiedni nagłówek HTPP
            Content-Type do użycia z XML-RPC. Możliwym powodem użycia własnego
            obiektu może być potrzeba logowania odpowiedzi, lub wysyłanie
            odpowiedzi spowrotem do STDOUT.
        </para>

        <para>
            Aby użyć własnej klasy odpowiedzi, użyj metody
            Zend_XmlRpc_Server::setResponseClass() przed wywołaniem handle().
        </para>
    </sect2>

    <sect2 id="zend.xmlrpc.server.fault">
        <title>Obsługa wyjątków poprzez odpowiedzi błędów</title>

        <para>
            Obiekt Zend_XmlRpc_Server łapie wyjątki wyrzucone przez uruchomioną
            metodę i generuje odpowiedź błędu (fault) wtedy gdy taki wyjątek
            zostanie złapany. Domyślnie informacje o wyjątkach i ich kody nie są
            używane w odpowiedzi błędu. Jest to celowe zachowanie chroniące twój
            kod; wiele wyjątków ujawnia dużo informacji o kodzie oraz środowisku,
            czemu programista powinien zapobiec (dobrym przykładem mogą być
            informacje o wyjątkach związanych z bazą danych)
        </para>

        <para>
            Klasy wyjątków, które mają być użyte jako odpowiedzi błędów mogą być
            dodane do listy dozwolonych wyjątków. Aby to zrobić wystarczy użyć
            metody Zend_XmlRpc_Server_Fault::attachFaultException() w celu
            przekazania klasy wyjątku do listy dozwolonych wyjątków:
        </para>

        <programlisting role="php"><![CDATA[
Zend_XmlRpc_Server_Fault::attachFaultException('My_Project_Exception');
]]>
        </programlisting>

        <para>
            Jeśli dodasz do listy wyjątków klasę wyjątku z którego dziedziczą
            inne wyjątki, możesz w ten sposób dodać do listy całą rodzinę
            wyjątków za jednym razem. Wyjątki Zend_XmlRpc_Server_Exceptions
            zawsze znajdują się na liście dozwolonych wyjątków, aby pozwolić na
            informowanie o specyficznych wewnętrznych błędach (niezdefiniowanie
            metody itp.).
        </para>

        <para>
            Każdy wyjątek spoza listy dozwolonych wyjątków spowoduje
            wygenerowanie odpowiedzi błędu o kodzie '404' i informacji
            'Unknown error' (Nieznany błąd).
        </para>
    </sect2>

    <sect2 id="zend.xmlrpc.server.caching">
        <title>Buforowanie definicji serwera pomiędzy żądaniami</title>
        <para>
            Dołączanie wielu klas do instancji serwera XML-RPC może zajmować
            wiele zasobów; za pomocą Reflection API (przez Zend_Server_Reflection)
            musi być dokonana introspekcja każdej klasy co w rezultacie wygeneruje
            listę wszystkich możliwych sygnatur metod w celu przekazania jej
            do klasy serwera.
        </para>
        <para>
            Aby zredukować straty wydajności, możemy użyć obiektu
            Zend_XmlRpc_Server_Cache do buforowania definicji serwera pomiędzy
            żądaniami. Gdy połączymy to z funkcją __autoload(), może to mocno
            zwiększyć wydajność.
        </para>
        <para>
            Przykładowe użycie:
        </para>
        <programlisting role="php"><![CDATA[
function __autoload($class)
{
    Zend_Loader::loadClass($class);
}

$cacheFile = dirname(__FILE__) . '/xmlrpc.cache';
$server = new Zend_XmlRpc_Server();

if (!Zend_XmlRpc_Server_Cache::get($cacheFile, $server)) {
    require_once 'My/Services/Glue.php';
    require_once 'My/Services/Paste.php';
    require_once 'My/Services/Tape.php';

    $server->setClass('My_Services_Glue', 'glue');   // przestrzeń nazw glue
    $server->setClass('My_Services_Paste', 'paste'); // przestrzeń nazw paste
    $server->setClass('My_Services_Tape', 'tape');   // przestrzeń nazw tape

    Zend_XmlRpc_Server_Cache::save($cacheFile, $server);
}

echo $server->handle();
]]>
        </programlisting>
        <para>
            Powyższy przykład próbuje pobrać definicję serwera z pliku bufora
            xmlrpc.cache znajdującego się w tym samym katalogu co skrypt. Jeśli
            się to nie uda, załaduje on potrzebne klasy serwisu, dołączy do
            instancji serwera i spróbuje utworzyć nowy plik bufora z definicją
            sderwera.
        </para>
    </sect2>

    <sect2 id="zend.xmlrpc.server.use">
        <title>Przykład użycia</title>
        <para>
            Poniżej znajduje się kilka przykładów użycia, pokazując pełne
            spektrum opcji dostępnych dla programistów. Każdy z przykładów
            użycia jest oparty na poprzednich przykładach.
        </para>
        <sect3 id="zend.xmlrpc.server.use.case1">
            <title>Podstawowe użycie</title>

            <para>
                Poniższy przykład dołącza funkcję jaką uruchamialną przez
                XML-RPC metodę i obsługuje przychodzące wywołania.
            </para>

            <programlisting role="php"><![CDATA[
/**
 * Zwraca sumę MD5 zadanej wartości
 *
 * @param string $value wartość do obliczenia sumy md5
 * @return string MD5 suma wartości
 */
function md5Value($value)
{
    return md5($value);
}

$server = new Zend_XmlRpc_Server();
$server->addFunction('md5Value');
echo $server->handle();
]]>
            </programlisting>
        </sect3>

        <sect3 id="zend.xmlrpc.server.use.case2">
            <title>Dołączanie klasy</title>

            <para>
                Poniższy przykład pokazuje dołączanie publicznych metod klasy
                jako uruchamialnych metod XML-RPC.
            </para>

            <programlisting role="php"><![CDATA[
$server = new Zend_XmlRpc_Server();
$server->setClass('Services_Comb');
echo $server->handle();
]]>
            </programlisting>
        </sect3>

        <sect3 id="zend.xmlrpc.server.use.case3">
            <title>Dołączanie wielu klas używając przestrzeni nazw</title>

            <para>
                Poniższy przykład pokazuje dołączanie kilku klas, każdej z
                własną przestrzenią nazw.
            </para>

            <programlisting role="php"><![CDATA[
$server = new Zend_XmlRpc_Server();
$server->setClass('Services_Comb', 'comb');   // metody wywoływane jako comb.*
$server->setClass('Services_Brush', 'brush'); // metody wywoływane jako brush.*
$server->setClass('Services_Pick', 'pick');   // metody wywoływane jako pick.*
echo $server->handle();
]]>
            </programlisting>
        </sect3>

        <sect3 id="zend.xmlrpc.server.use.case4">
            <title>Określenie wyjątków dla odpowiedzi błędów</title>

            <para>
                Poniższy przykład pozwala dowolnej klasie pochodzącej od
                Services_Exception na przekazywanie informacji o wyjątkach w
                postaci kodu i wiadomości w odpowiedzi błędu.
            </para>

            <programlisting role="php"><![CDATA[
// Pozwala na wyrzucanie wyjątku Services_Exceptions dla odpowiedzi błędu
Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');

$server = new Zend_XmlRpc_Server();
$server->setClass('Services_Comb', 'comb');   // metody wywoływane jako comb.*
$server->setClass('Services_Brush', 'brush'); // metody wywoływane jako brush.*
$server->setClass('Services_Pick', 'pick');   // metody wywoływane jako pick.*
echo $server->handle();
]]>
            </programlisting>
        </sect3>

        <sect3 id="zend.xmlrpc.server.use.case5">
            <title>Użycie własnego obiektu żądania</title>

            <para>
                Poniższy przykład tworzy instancję własnego obiektu żądania i
                przekazuje go do obiektu serwera.
            </para>

            <programlisting role="php"><![CDATA[
// Pozwala na wyrzucanie wyjątku Services_Exceptions dla odpowiedzi błędu
Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');

$server = new Zend_XmlRpc_Server();
$server->setClass('Services_Comb', 'comb');   // metody wywoływane jako comb.*
$server->setClass('Services_Brush', 'brush'); // metody wywoływane jako brush.*
$server->setClass('Services_Pick', 'pick');   // metody wywoływane jako pick.*

// Tworzenie obiektu żądania
$request = new Services_Request();

echo $server->handle($request);
]]>
            </programlisting>
        </sect3>

        <sect3 id="zend.xmlrpc.server.use.case6">
            <title>Użycie własnego obiektu odpowiedzi</title>

            <para>
                Poniższy przykład pokazuje określanie własnej klasy odpowiedzi
                dla zwracanej odpowiedzi.
            </para>

            <programlisting role="php"><![CDATA[
// Pozwala na wyrzucanie wyjątku Services_Exceptions dla odpowiedzi błędu
Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');

$server = new Zend_XmlRpc_Server();
$server->setClass('Services_Comb', 'comb');   // metody wywoływane jako comb.*
$server->setClass('Services_Brush', 'brush'); // metody wywoływane jako brush.*
$server->setClass('Services_Pick', 'pick');   // metody wywoływane jako pick.*

// Utwórz obiekt żądania
$request = new Services_Request();

// Użyj własnego obiektu żądania
$server->setResponseClass('Services_Response');

echo $server->handle($request);
]]>
            </programlisting>
        </sect3>

        <sect3 id="zend.xmlrpc.server.use.case7">
            <title>Buforowanie definicji serwera pomiędzy żądaniami</title>

            <para>
                Poniższy przykład pokazuje buforowanie definicji serwera pomiędzy
                żądaniami.
            </para>

            <programlisting role="php"><![CDATA[
// Określ plik cache
$cacheFile = dirname(__FILE__) . '/xmlrpc.cache';

// Pozwala na wyrzucanie wyjątku Services_Exceptions dla odpowiedzi błędu
Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');

$server = new Zend_XmlRpc_Server();

// Spróbuj pobrać definicje serwera z bufora
if (!Zend_XmlRpc_Server_Cache::get($cacheFile, $server)) {
    $server->setClass('Services_Comb', 'comb');   // metody wywoływane jako comb.*
    $server->setClass('Services_Brush', 'brush'); // metody wywoływane jako brush.*
    $server->setClass('Services_Pick', 'pick');   // metody wywoływane jako pick.*

    // Zapisz cache
    Zend_XmlRpc_Server_Cache::save($cacheFile, $server));
}

// Utwórz obiekt żądania
$request = new Services_Request();

// Użyj własnej klasy odpowiedzi
$server->setResponseClass('Services_Response');

echo $server->handle($request);
]]>
            </programlisting>
        </sect3>
    </sect2>
</sect1>