[MANUAL] English:
[zend.git] / documentation / manual / ru / module_specs / Zend_XmlRpc_Client.xml
blob2ff9fd5475d4325924392b9a436a0ba7993423e2
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect1 id="zend.xmlrpc.client">
4     <title>Zend_XmlRpc_Client</title>
6     <sect2 id="zend.xmlrpc.client.introduction">
7         <title>Введение</title>
9         <para>
10             Zend Framework поддерживает клиентское использование удаленных
11             XML-RPC сервисов через пакет <classname>Zend_XmlRpc_Client</classname>.
12             Его основные возможности включают в себя автоматическое
13             преобразование типов между PHP и XML-RPC, прокси-объект сервера и
14             доступ к средствам интроспекции на сервере.
15         </para>
17     </sect2>
20     <sect2 id="zend.xmlrpc.client.method-calls">
21         <title>Вызов методов</title>
23         <para>
24             Конструктор <classname>Zend_XmlRpc_Client</classname> принимает URL удаленного
25             XML-RPC сервера в качестве первого параметра. Новый экземпляр класса
26             может использоваться для вызова любых удаленных методов этого
27             сервера.
28         </para>
30         <para>
31             Для вызова удаленного метода через клиентa XML-RPC инстанцируйте его
32             и используйте его метод <code>call()</code>. В примере ниже
33             используется демонстрационный XML-RPC сервер на веб-сайте Zend
34             Framework. Вы можете использовать его для тестирования или изучения
35             компонент <classname>Zend_XmlRpc</classname>.
36         </para>
38         <example id="zend.xmlrpc.client.method-calls.example-1">
39             <title>Вызов метода XML-RPC</title>
40             <programlisting language="php"><![CDATA[
41 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
43 echo $client->call('test.sayHello');
45 // hello
46 ]]></programlisting>
47         </example>
49         <para>
50             Значение XML-RPC, возвращаемое при вызове удаленного метода, будет
51             автоматически приведено к эквивалентному типу в PHP. В примере выше
52             возвращается строка (тип <type>String</type> в PHP), и она уже
53             готова к применению.
54         </para>
56         <para>
57             Первый параметр метода <code>call()</code> принимает имя удаленного
58             метода, вызов которого требуется. Если удаленный метод требует
59             каких-либо параметров, то они могут быть переданы методу
60             <code>call()</code> через второй необязательный параметр в виде
61             массива значений для последующей передачи удаленному методу:
62         </para>
64         <example id="zend.xmlrpc.client.method-calls.example-2">
65             <title>Вызов метода XML-RPC с параметрами</title>
66             <programlisting language="php"><![CDATA[
67 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
69 $arg1 = 1.1;
70 $arg2 = 'foo';
72 $result = $client->call('test.sayHello', array($arg1, $arg2));
74 // возвращаемый результат имеет "родной" для PHP тип
75 ]]></programlisting>
76         </example>
78         <para>
79             Если удаленный метод не требует параметров, то этот необязательный
80             параметр можно опустить или передать пустой массив. Массив
81             параметров для удаленного метода может содержать значения "родного"
82             для PHP типа, объекты <classname>Zend_XmlRpc_Value</classname>, либо
83             и то и другое вместе.
84         </para>
86         <para>
87             Метод <code>call()</code> будет автоматически преобразовывать ответ
88             XML-RPC и возвращать его в эквивалентном "родном" для PHP типе.
89             Кроме этого, можно получить объект <classname>Zend_XmlRpc_Response</classname>
90             для возвращенного значения, вызвав метод
91             <code>getLastResponse()</code> после вызова <code>call()</code>.
92         </para>
93     </sect2>
95     <sect2 id="zend.xmlrpc.value.parameters">
96         <title>Типы и их преобразование</title>
97         <para>
98             Некоторые удаленные методы требуют передачи параметров при вызове.
99             Они передаются методу <code>call()</code> объекта
100             <classname>Zend_XmlRpc_Client</classname> в виде массива во втором параметре.
101             Любой параметр может быть передан в "родном" для PHP типе, который
102             будет автоматически преобразован в соответствующий тип XML-RPC,
103             или как объект, представляющий
104             определенный тип в XML-RPC (один из объектов
105             <classname>Zend_XmlRpc_Value</classname>).
106         </para>
108         <sect3 id="zend.xmlrpc.value.parameters.php-native">
109             <title>Параметры в "родном" для PHP типе</title>
110             <para>
111                 Параметры могут передаваться методу <code>call()</code> как
112                 переменные "родного" для PHP типа, это могут быть типы
113                 <type>String</type>, <code>integer</code>, <code>float</code>,
114                 <type>Boolean</type>, <type>Array</type> или
115                 <code>object</code>. В этом случае каждый из этих типов будет
116                 автоматически определен и преобразован в один из типов XML-RPC
117                 согласно следующей таблице:
118             </para>
120             <table>
121                 <title>Преобразование типов PHP и XML-RPC</title>
122                 <tgroup cols="2">
123                     <thead>
124                         <row>
125                             <entry>Тип в PHP</entry>
126                             <entry>Тип в XML-RPC</entry>
127                         </row>
128                     </thead>
129                     <tbody>
130                         <row>
131                             <entry>integer</entry>
132                             <entry>int</entry>
133                         </row>
134                         <row>
135                             <entry>double</entry>
136                             <entry>double</entry>
137                         </row>
138                         <row>
139                             <entry>boolean</entry>
140                             <entry>boolean</entry>
141                         </row>
142                         <row>
143                             <entry>string</entry>
144                             <entry>string</entry>
145                         </row>
146                         <row>
147                             <entry>array</entry>
148                             <entry>array</entry>
149                         </row>
150                         <row>
151                             <entry>array (ассоциативный)</entry>
152                             <entry>struct</entry>
153                         </row>
154                         <row>
155                             <entry>object</entry>
156                             <entry>array</entry>
157                         </row>
158                     </tbody>
159                 </tgroup>
160             </table>
162             <note>
163                 <title>Какому типу будет соответствовать пустой массив?</title>
165                 <para>
166                     Передача пустого массива методу XML-RPC несет в себе
167                     потенциальную проблему, т.к. он может быть представлен
168                     и массивом, и структурой. <classname>Zend_XmlRpc_Client</classname>
169                     в этом случае делает запрос к методу сервера
170                     <code>system.methodSignature</code> для определения
171                     требуемого типа аргумента и производит соответствующее
172                     преобразование.
173                 </para>
175                 <para>
176                     Но такое решение само по себе тоже может быть источником
177                     проблем. Во-первых, сервера, которые не поддерживают метод
178                     <code>system.methodSignature</code>, будут журналировать это
179                     как ошибочные вызовы, в этом случае
180                     <classname>Zend_XmlRpc_Client</classname> будет производить
181                     преобразование значения к типу array в XML-RPC.
182                     Кроме того, это приводит к дополнительным вызовам к
183                     удаленному серверу в случае передачи аргументов в виде
184                     массивов.
185                 </para>
187                 <para>
188                     Для того, чтобы полностью отключить эти вызовы, вы можете
189                     вызвать метод <code>setSkipSystemLookup()</code> до
190                     собственно запроса к методу XML-RPC:
191                 </para>
193                 <programlisting language="php"><![CDATA[
194 $client->setSkipSystemLookup(true);
195 $result = $client->call('foo.bar', array(array()));
196 ]]></programlisting>
197             </note>
199         </sect3>
201         <sect3 id="zend.xmlrpc.value.parameters.xmlrpc-value">
202             <title>Параметры в виде объектов Zend_XmlRpc_Value</title>
203             <para>
204                 Параметры могут также создаваться как экземпляры
205                 <classname>Zend_XmlRpc_Value</classname> для точного указания типа
206                 XML-RPC. Основные причины для этого:
208                 <itemizedlist>
209                     <listitem>
210                         <para>
211                             Вы хотите быть уверенными в том, что
212                             процедуре передается корректный тип параметра
213                             (т.е. процедура требует целочисленное значение, а
214                             вы можете получать его из БД в виде
215                             строки)
216                         </para>
217                     </listitem>
218                     <listitem>
219                         <para>
220                             Удаленная процедура требует тип <code>base64</code>
221                             или <code>dateTime.iso8601</code> (которых нет среди
222                             "родных" для PHP типов).
223                         </para>
224                     </listitem>
225                     <listitem>
226                         <para>
227                             Автоматическое преобразование может работать
228                             неправильно (например, вы хотите передать пустую
229                             структуру XML-RPC в качестве параметра. Пустая структура
230                             представляется в PHP пустым массивом, но если вы
231                             передаете пустой массив в качестве параметра, то он
232                             преобразовывается в массив XML-RPC, т.к. не
233                             является ассоциативным массивом)
234                         </para>
235                     </listitem>
236                 </itemizedlist>
237             </para>
239             <para>
240                 Есть два способа создания объектов <classname>Zend_XmlRpc_Value</classname> ―
241                 непосредственное инстанцирование одного из подклассов
242                 <classname>Zend_XmlRpc_Value</classname> и использование статического
243                 фабричного метода
244                 <classname>Zend_XmlRpc_Value::getXmlRpcValue()</classname>.
245             </para>
247             <table id="zend.xmlrpc.value.parameters.xmlrpc-value.table-1">
248                 <title>Объекты Zend_XmlRpc_Value для типов XML-RPC</title>
249                 <tgroup cols="3">
250                     <thead>
251                         <row>
252                             <entry>Тип XML-RPC</entry>
253                             <entry>Константа <classname>Zend_XmlRpc_Value</classname></entry>
254                             <entry>Объект <classname>Zend_XmlRpc_Value</classname></entry>
255                         </row>
256                     </thead>
257                     <tbody>
258                         <row>
259                             <entry>int</entry>
260                             <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER</code></entry>
261                             <entry><classname>Zend_XmlRpc_Value_Integer</classname></entry>
262                         </row>
263                         <row>
264                             <entry>double</entry>
265                             <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE</code></entry>
266                             <entry><classname>Zend_XmlRpc_Value_Double</classname></entry>
267                         </row>
268                         <row>
269                             <entry>boolean</entry>
270                             <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN</code></entry>
271                             <entry><classname>Zend_XmlRpc_Value_Boolean</classname></entry>
272                         </row>
273                         <row>
274                             <entry>string</entry>
275                             <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_STRING</code></entry>
276                             <entry><classname>Zend_XmlRpc_Value_String</classname></entry>
277                         </row>
278                         <row>
279                             <entry>base64</entry>
280                             <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64</code></entry>
281                             <entry><classname>Zend_XmlRpc_Value_Base64</classname></entry>
282                         </row>
283                         <row>
284                             <entry>dateTime.iso8601</entry>
285                             <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME</code></entry>
286                             <entry><classname>Zend_XmlRpc_Value_DateTime</classname></entry>
287                         </row>
288                         <row>
289                             <entry>array</entry>
290                             <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY</code></entry>
291                             <entry><classname>Zend_XmlRpc_Value_Array</classname></entry>
292                         </row>
293                         <row>
294                             <entry>struct</entry>
295                             <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT</code></entry>
296                             <entry><classname>Zend_XmlRpc_Value_Struct</classname></entry>
297                         </row>
298                     </tbody>
299                 </tgroup>
300             </table>
302             <para>
303                 <note>
304                     <title>Автоматическое преобразование</title>
305                     <para>
306                         Когда создается новый объект
307                         <classname>Zend_XmlRpc_Value</classname>, его значение
308                         устанавливается в "родном" для PHP типе. Тип в PHP будет
309                         преобразован к определенному типу средствами PHP.
310                         Например, если в качестве значения для объекта
311                         <classname>Zend_XmlRpc_Value_Integer</classname> была передана
312                         строка, то она будет преобразована через
313                         <code>(int)$value</code>.
314                     </para>
315                 </note>
316             </para>
317         </sect3>
318     </sect2>
320     <sect2 id="zend.xmlrpc.client.requests-and-responses">
321         <title>Прокси-объект сервера</title>
322         <para>
323             Другим способом вызова удаленных методов через клиента XML-RPC
324             является использование "заместителя" сервера. Это PHP-объект,
325             который предоставляет интерфейс к удаленному пространству имен
326             XML-RPC, делая работу с ним максимально близкой к работе с обычным
327             объектом в PHP.
328         </para>
330         <para>
331             Для того, чтобы инстанцировать "заместителя" сервера, вызовите
332             метод <code>getProxy()</code> объекта
333             <classname>Zend_XmlRpc_Client</classname>. Он вернет объект класса
334             <classname>Zend_XmlRpc_Client_ServerProxy</classname>.
335             Любые вызовы методов прокси-объекта
336             сервера будет перенаправлены к удаленному серверу, параметры могут
337             передаваться так же, как и для любых других методов в PHP.
338         </para>
340         <example id="zend.xmlrpc.client.requests-and-responses.example-1">
341             <title>Прокси-объект к пространству имен по умолчанию</title>
342             <programlisting language="php"><![CDATA[
343 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
345 // Создание прокси-объекта к пространству имен по умолчанию
346 $server = $client->getProxy();
348 $hello = $server->test->sayHello(1, 2);
349 // test.Hello(1, 2) возвращает "hello"
350 ]]></programlisting>
351         </example>
353         <para>
354             Метод <code>getProxy()</code> принимает необязательный аргумент,
355             указывающий, к какому пространству имен следует создать
356             прокси-объект. Если этот аргумент не был указан, то то будет
357             использоваться пространство имен по умолчанию. В следующем примере
358             используется пространство имен <code>test</code>:
359         </para>
361         <example id="zend.xmlrpc.client.requests-and-responses.example-2">
362             <title>Прокси-объект к произвольному пространству имен</title>
363             <programlisting language="php"><![CDATA[
364 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
366 // Создание прокси-объекта к пространству имен "test"
367 $test  = $client->getProxy('test');
369 $hello = $test->sayHello(1, 2);
370 // test.Hello(1,2) возвращает "hello"
371 ]]></programlisting>
372         </example>
374         <para>
375             Если удаленный сервер поддерживает сколько угодно вложенные
376             пространства имен, то они также могут использоваться через
377             прокси-объект сервера. Например, если сервер в примере выше имеет
378             метод <code>test.foo.bar()</code>, то он может вызываться следующим
379             образом: <varname>$test->foo->bar()</varname>.
380         </para>
381     </sect2>
384     <sect2 id="zend.xmlrpc.client.error-handling">
385         <title>Обработка ошибок</title>
386         <para>
387             При вызове методов XML-RPC могут могут быть ошибки двух типов: HTTP и
388             XML-RPC. <classname>Zend_XmlRpc_Client</classname> распознает оба типа,
389             позволяя обнаруживать и отлавливать их независимо друг от друга.
390         </para>
392         <sect3 id="zend.xmlrpc.client.error-handling.http">
393             <title>Ошибки HTTP</title>
395             <para>
396                 Если произошла ошибка HTTP - например, удаленный HTTP-сервер
397                 вернул код <code>404 Not Found</code>, - то будет сгенерировано
398                 исключение <classname>Zend_XmlRpc_Client_HttpException</classname>.
399             </para>
401             <example id="zend.xmlrpc.client.error-handling.http.example-1">
402                 <title>Обработка ошибок HTTP</title>
404                 <programlisting language="php"><![CDATA[
405 $client = new Zend_XmlRpc_Client('http://foo/404');
407 try {
409     $client->call('bar', array($arg1, $arg2));
411 } catch (Zend_XmlRpc_HttpException $e) {
413     // $e->getCode() возвращает 404
414     // $e->getMessage() возвращает "Not Found"
417 ]]></programlisting>
418             </example>
420             <para>
421                 Независимо от того, какой клиент XML-RPC используется, всякий
422                 раз, когда происходит ошибка HTTP, генерируется исключение
423                 <classname>Zend_XmlRpc_Client_HttpException</classname>.
424             </para>
425         </sect3>
427         <sect3 id="zend.xmlrpc.client.error-handling.faults">
428             <title>Ошибки XML-RPC</title>
430             <para>
431                 Ошибка XML-RPC аналогична исключению в PHP. Это специальный тип,
432                 возвращаемый при вызове метода XML-RPC и включающий в себя код и
433                 сообщение ошибки. Ошибки XML-RPC обрабатываются по-разному,
434                 в зависимости от контекста использования
435                 <classname>Zend_XmlRpc_Client</classname>.
436             </para>
438             <para>
439                Если используется метод <code>call()</code> или прокси-объект
440                сервера, то ошибка XML-RPC приведет к тому, что будет
441                сгенерировано исключение
442                <classname>Zend_XmlRpc_Client_FaultException</classname>. Код и сообщение
443                исключения будут в точности соответствовать значениям в
444                возвращенном ответе с сообщением об ошибке.
445             </para>
447             <example id="zend.xmlrpc.client.error-handling.faults.example-1">
448                 <title>Обработка ошибок XML-RPC</title>
450                 <programlisting language="php"><![CDATA[
451 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
453 try {
455     $client->call('badMethod');
457 } catch (Zend_XmlRpc_FaultException $e) {
459     // $e->getCode() возвращает 1
460     // $e->getMessage() возвращает "Unknown method"
463 ]]></programlisting>
464             </example>
466             <para>
467                 Если для выполнения запроса используется метод
468                 <code>call()</code>, то в случае ошибки будет сгенерировано
469                 исключение <classname>Zend_XmlRpc_FaultException</classname>. Объект
470                 <classname>Zend_XmlRpc_Response</classname>, содержащий возвращенную
471                 ошибку, можно также получить через метод
472                 <code>getLastResponse()</code>.
473             </para>
475             <para>
476                 Если для выполнения запроса используется метод
477                 <code>doRequest()</code>, то исключение не генерируется. Вместо
478                 этого будет возвращен объект <classname>Zend_XmlRpc_Response</classname>,
479                 содержащий возвращенную XML-RPC ошибку. Проверить, содержит ли
480                 объект ошибку, можно через метод <code>isFault()</code> объекта
481                 <classname>Zend_XmlRpc_Response</classname>.
482             </para>
483         </sect3>
485     </sect2>
487     <sect2 id="zend.xmlrpc.client.introspection">
488         <title>Интроспекция сервера</title>
489         <para>
490             Некоторые XML-RPC сервера поддерживают интроспекцию методов
491             под пространством имен <code>system.</code>.
492             <classname>Zend_XmlRpc_Client</classname> предоставляет специальную поддержку
493             для серверов с этой возможностью.
494         </para>
496         <para>
497             Экземпляр <classname>Zend_XmlRpc_Client_ServerIntrospection</classname> может
498             быть получен через вызов метода <code>getIntrospector()</code>
499             класса <classname>Zend_XmlRpcClient</classname>. Далее он может использоваться
500             для выполнения операций интроспекции на сервере.
501         </para>
502     </sect2>
504     <sect2 id="zend.xmlrpc.client.request-to-response">
505         <title>От запроса к ответу</title>
506         <para>
507             Метод <code>call()</code> экземпляра <classname>Zend_XmlRpc_Client</classname>
508             в процессе выполнения строит объект запроса
509             (<classname>Zend_XmlRpc_Request</classname>) и передает его другому методу
510             <code>doRequest()</code>, который возвращает объект ответа
511             (<classname>Zend_XmlRpc_Response</classname>).
512         </para>
514         <para>
515             Метод <code>doRequest()</code> также доступен для непосредственного
516             использования:
517         </para>
519         <example id="zend.xmlrpc.client.request-to-response.example-1">
520             <title>Выполнение запроса</title>
522             <programlisting language="php"><![CDATA[
523 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
525 $request = new Zend_XmlRpc_Request();
526 $request->setMethod('test.sayHello');
527 $request->setParams(array('foo', 'bar'));
529 $client->doRequest($request);
531 // $server->getLastRequest() возвращает экземпляр Zend_XmlRpc_Request
532 // $server->getLastResponse() возвращает экземпляр Zend_XmlRpc_Response
533 ]]></programlisting>
534         </example>
536         <para>
537             После того, как через клиента был вызван метод XML-RPC (через
538             методы <code>call()</code>, <code>doRequest()</code> или через
539             прокси-объект сервера), всегда можно получить объекты последнего запроса и
540             ответа на него через методы <code>getLastRequest()</code> и
541             <code>getLastResponse()</code> соответственно.
542         </para>
543     </sect2>
545     <sect2 id="zend.xmlrpc.client.http-client">
546         <title>HTTP-клиент и тестирование</title>
548         <para>
549             Ни в одном из предыдущих примеров не указывался HTTP-клиент. В
550             этом случае создается новый экземпляр <classname>Zend_Http_Client</classname>
551             с настройками по умолчанию и автоматически используется
552             клиентом <classname>Zend_XmlRpc_Client</classname>.
553         </para>
555         <para>
556             HTTP-клиент может быть получен в любое время через метод
557             <code>getHttpClient()</code>. В большинстве случаев достаточно
558             использование HTTP-клиента по умолчанию. Тем не менее, метод
559             <code>setHttpClient()</code> позволяет установить HTTP-клиент,
560             отличный от принятого по умолчанию.
561         </para>
563         <para>
564             <code>setHttpClient()</code> может быть полезен при
565             unit-тестировании. При совместном использовании с
566             <classname>Zend_Http_Client_Adapter_Test</classname> можно имитировать
567             удаленные сервисы для тестирования. В качестве примера реализации
568             рассмотрите unit-тесты для <classname>Zend_XmlRpc_Client</classname>,
569             входящие в поставку Zend Framework.
570         </para>
571     </sect2>
573 </sect1>
574 <!--
575 vim:se ts=4 sw=4 et: