[MANUAL] English:
[zend.git] / documentation / manual / ru / module_specs / Zend_XmlRpc_Server.xml
blobf13d722d0b4f5b3eed6942661fbaf506eb5f5f18
1 <?xml version="1.0" encoding="UTF-8"?>\r
2 <!-- Reviewed: no -->\r
3 <sect1 id="zend.xmlrpc.server">\r
4     <title>Zend_XmlRpc_Server</title>\r
5 \r
6     <sect2 id="zend.xmlrpc.server.introduction">\r
7         <title>Введение</title>\r
8 \r
9         <para>\r
10             <classname>Zend_XmlRpc_Server</classname> задуман как полнофункциональный XML-RPC сервер,\r
11             следующий <ulink url="http://www.xmlrpc.com/spec">спецификациям,\r
12             приведенным на www.xmlrpc.com</ulink>. Кроме того, он реализует метод\r
13             <code>system.multicall()</code>, позволяющий объединять несколько\r
14             запросов в один.\r
15         </para>\r
16     </sect2>\r
18     <sect2 id="zend.xmlrpc.server.usage">\r
19         <title>Основы использования</title>\r
21         <para>\r
22             Простой пример использования:\r
23         </para>\r
25         <programlisting language="php"><![CDATA[\r
26 $server = new Zend_XmlRpc_Server();\r
27 $server->setClass('My_Service_Class');\r
28 echo $server->handle();\r
29 ]]></programlisting>\r
30     </sect2>\r
32     <sect2 id="zend.xmlrpc.server.structure">\r
33         <title>Структура сервера</title>\r
35         <para>\r
36             <classname>Zend_XmlRpc_Server</classname> состоит из множества компонент от собственно\r
37             сервера до объектов запросов, ответов и сообщений об ошибке.\r
38         </para>\r
40         <para>\r
41             Для загрузки <classname>Zend_XmlRpc_Server</classname> разработчик должен прикрепить классы\r
42             или функции к серверу через методы <code>setClass()</code> и\r
43             <code>addFunction()</code>.\r
44         </para>\r
46         <para>\r
47             После этого можно передать объект <classname>Zend_XmlRpc_Request</classname>\r
48             методу <code>Zend_XmlRpc_Server::handle()</code>; если он не был\r
49             передан, то будет проинциализирован объект\r
50             <classname>Zend_XmlRpc_Request_Http</classname>, при этом данные запроса\r
51             берутся из <code>php://input</code>.\r
52         </para>\r
54         <para>\r
55             Затем <code>Zend_XmlRpc_Server::handle()</code> пытается определить\r
56             подходящий обработчик, основываясь на запрошенном методе. После\r
57             этого он возвращает объект ответа, основанный на\r
58             <classname>Zend_XmlRpc_Response</classname>, или объект сообщения\r
59             об ошибке <classname>Zend_XmlRpc_Server_Fault</classname>. Эти объекты имеют\r
60             метод <code>__toString()</code>, который возвращает валидный XML-RPC\r
61             ответ в формате XML, что позволяет выводить эти объекты\r
62             через <code>echo</code>.\r
63         </para>\r
64     </sect2>\r
66     <sect2 id="zend.xmlrpc.server.conventions">\r
67         <title>Соглашения</title>\r
68         <para>\r
69             <classname>Zend_XmlRpc_Server</classname> позволяет прикреплять функции и\r
70             методы класса - т.н. доступные для диспетчеризации XML-RPC\r
71             методы. С помощью <classname>Zend_Server_Reflection</classname> он проводит интроспекцию по\r
72             всем прикрепленным методам, используя docblock'и функций и методов\r
73             для установки текста справки и сигнатур методов.\r
74         </para>\r
76         <para>\r
77             Не обязательно, чтобы типы в XML-RPC в точности соответствовали\r
78             типам в PHP. Тем не менее, для наилучшего результата код пытается\r
79             угадать наиболее подходящий тип, основываясь на значениях\r
80             дескрипторов @param и @return. Некоторые типы в XML-RPC не имеют\r
81             эквивалентов в PHP и должны указываться в PHPDoc. В их список\r
82             входят:\r
83         </para>\r
85         <itemizedlist>\r
86             <listitem>\r
87                 <para>\r
88                     dateTime.iso8601 - дата в формате YYYYMMDDTHH:mm:ss\r
89                 </para>\r
90             </listitem>\r
91             <listitem><para>base64 - данные, закодированные по алгоритму base64</para></listitem>\r
92             <listitem><para>struct - любой ассоциативный массив</para></listitem>\r
93         </itemizedlist>\r
95         <para>\r
96             Пример того, как указывается XML-RPC тип\r
97         </para>\r
99         <programlisting language="php"><![CDATA[\r
100 /**\r
101 * Это пример функции\r
103 * @param base64 $val1 Закодированные в base64 данные\r
104 * @param dateTime.iso8601 $val2 Дата в ISO-формате\r
105 * @param struct $val3 Ассоциативный массив\r
106 * @return struct\r
107 */\r
108 function myFunc($val1, $val2, $val3)\r
110 ]]></programlisting>\r
112         <para>\r
113             PhpDocumentor не проводит валидацию типов, определенных для\r
114             параметров или возвращаемых значений, поэтому это не должно\r
115             влиять на вашу документацию по API. Указание типов необходимо,\r
116             если сервер проводит валидацию передаваемых методу параметров.\r
117         </para>\r
119         <para>\r
120             Будет совершенно корректным с точки зрения синтаксиса определять\r
121             набор возможных типов как для параметров, так и для возвращаемых\r
122             значений; спецификация XML-RPC даже рекомендует, чтобы\r
123             system.methodSignature возвращал массив всех\r
124             возможных сигнатур метода (т.е. все возможные комбинации параметров\r
125             и возвращаемых значений). Вы можете делать это в точности так же,\r
126             как это обычно делается для PhpDocumentor - с использованием\r
127             оператора '|':\r
128         </para>\r
130         <programlisting language="php"><![CDATA[\r
131 /**\r
132 * Это пример функции\r
134 * @param string|base64 $val1 Строка или закодированные в base64 данные\r
135 * @param string|dateTime.iso8601 $val2 Строка или дата в ISO-формате\r
136 * @param array|struct $val3 Обычный нумерованный массив или ассоциативный массив\r
137 * @return boolean|struct\r
138 */\r
139 function myFunc($val1, $val2, $val3)\r
142 ]]></programlisting>\r
144         <para>\r
145             Тем не менее, следует учесть, что обилие сигнатур может сбивать с\r
146             толку разработчиков, использующих данный веб-сервис. Другими словами,\r
147             следует стремится к тому, чтобы XML-RPC метод имел только одну\r
148             сигнатуру.\r
149         </para>\r
150     </sect2>\r
152     <sect2 id="zend.xmlrpc.server.namespaces">\r
153         <title>Использование пространств имен</title>\r
155         <para>\r
156             В XML-RPC есть такое понятие, как пространства имен. Они позволяют\r
157             группировать методы посредством разделенных точкой\r
158             имен пространств. Это позволяет предотвратить конфликты имен\r
159             методов, предоставляемых разными классами. Например, обычно XML-RPC\r
160             сервер предоставляет несколько методов в пространстве имен 'system':\r
161         </para>\r
163         <itemizedlist>\r
164             <listitem><para>system.listMethods</para></listitem>\r
165             <listitem><para>system.methodHelp</para></listitem>\r
166             <listitem><para>system.methodSignature</para></listitem>\r
167         </itemizedlist>\r
169         <para>\r
170             В нашем случае они соответствуют методам с теми же именами в\r
171             <classname>Zend_XmlRpc_Server</classname>.\r
172         </para>\r
174         <para>\r
175             Если необходимо добавить пространства имен для обслуживаемых\r
176             методов, то просто укажите пространство имен в качестве параметра\r
177             при вызове соответствующего метода для прикрепления функции или\r
178             класса:\r
179         </para>\r
181         <programlisting language="php"><![CDATA[\r
182 // Все открытые методы в My_Service_Class можно будет вызывать как\r
183 // myservice.имя_метода\r
184 $server->setClass('My_Service_Class', 'myservice');\r
186 // Функцию 'somefunc' можно будет вызывать как funcs.somefunc\r
187 $server->addFunction('somefunc', 'funcs');\r
188 ]]></programlisting>\r
189     </sect2>\r
191     <sect2 id="zend.xmlrpc.server.request">\r
192         <title>Использование своих объектов запросов</title>\r
194         <para>\r
195             В большинстве случаев вы можете использовать включенный по умолчанию\r
196             в <classname>Zend_XmlRpc_Server</classname> тип запроса –\r
197             <classname>Zend_XmlRpc_Request_Http</classname>. Тем не\r
198             менее, может потребоваться использование XML-RPC в окружениях\r
199             CLI, GUI и т.п., журналирование приходящих запросов. Для этого вы\r
200             можете создавать свои классы запросов, которые наследуют от\r
201             <classname>Zend_XmlRpc_Request</classname>. Важно помнить при этом, что\r
202             методы <code>getMethod()</code> и <code>getParams()</code>\r
203             должны быть реализованы таким\r
204             образом, чтобы XML-RPC сервер мог получить из них ту информацию,\r
205             которая необходима для обработки запроса.\r
206         </para>\r
207     </sect2>\r
209     <sect2 id="zend.xmlrpc.server.response">\r
210         <title>Использование своих объектов ответов</title>\r
212         <para>\r
213             Как и в случае объектов запросов, <classname>Zend_XmlRpc_Server</classname> может\r
214             возвращать объекты других типов; по умолчанию возвращается\r
215             объект <classname>Zend_XmlRpc_Response_Http</classname>, который отправляет соответствующий\r
216             XML-RPC заголовок <code>Content-Type</code>. Целью создания своих\r
217             типов ответов могут быть возможность журналирования\r
218             ответов или отправки ответов обратно в STDOUT.\r
219         </para>\r
221         <para>\r
222             Для того чтобы использовать свой класс ответа, вызывайте\r
223             метод <code>Zend_XmlRpc_Server::setResponseClass()</code> до вызова\r
224             метода <code>handle()</code>.\r
225         </para>\r
226     </sect2>\r
228     <sect2 id="zend.xmlrpc.server.fault">\r
229         <title>Обработка исключений через сообщения об ошибке</title>\r
231         <para>\r
232             <classname>Zend_XmlRpc_Server</classname> отлавливает исключения, сгенерированные\r
233             вызываемым методом и генерирует ответ с сообщением об ошибке сразу,\r
234             как только исключение поймано. Однако по умолчанию сообщение и код\r
235             исключения не используются в ответе с сообщением об ошибке. Это\r
236             сделано намеренно для того, чтобы защитить ваш код, т.к. многие\r
237             исключения могут выдавать информацию о коде приложения или\r
238             среде выполнения, обычно предназначенные разработчику.\r
239         </para>\r
241         <para>\r
242             Тем не менее, можно включать классы исключений в список разрешенных\r
243             к отображению в ответах с сообщением об ошибке. Для этого\r
244             используйте <code>Zend_XmlRpc_Server_Fault::attachFaultException()</code>\r
245             для включения данного класса исключения в список разрешенных.\r
246         </para>\r
248         <programlisting language="php"><![CDATA[\r
249 Zend_XmlRpc_Server_Fault::attachFaultException('My_Project_Exception');\r
250 ]]></programlisting>\r
252         <para>\r
253             Если вы используете класс исключения, от которого наследуют другие\r
254             исключения в проекте, то можете cразу включить все "семейство"\r
255             исключений в список разрешенных. Исключения\r
256             <classname>Zend_XmlRpc_Server_Exception</classname>\r
257             всегда находится в списке разрешенных исключений для того, чтобы\r
258             сообщать об отдельных внутренних ошибках (вызов несуществующего\r
259             метода и т.д.).\r
260         </para>\r
262         <para>\r
263             На любое исключение, не включенное в список разрешенных, будет\r
264             генерироваться ответ с кодом ошибки '404' и сообщением 'Unknown\r
265             error'.\r
266         </para>\r
267     </sect2>\r
269     <sect2 id="zend.xmlrpc.server.caching">\r
270         <title>Кэширование определений сервера между запросами</title>\r
271         <para>\r
272             Прикрепление большого количества классов к экземпляру XML-RPC\r
273             сервера может отнимать много ресурсов – каждый класс должен\r
274             проверяться с использованием Reflection API (через\r
275             <classname>Zend_Server_Reflection</classname>), который создает список всех возможных\r
276             сигнатур методов для передачи классу сервера.\r
277         </para>\r
278         <para>\r
279             Чтобы снизить ущерб производительности, можно использовать\r
280             <classname>Zend_XmlRpc_Server_Cache</classname> для кэширования определений сервера между\r
281             запросами. Если комбинировать его с <code>__autoload()</code>, то это может дать\r
282             значительный прирост производительности.\r
283         </para>\r
284         <para>\r
285             Пример использования:\r
286         </para>\r
287         <programlisting language="php"><![CDATA[\r
288 function __autoload($class)\r
290     Zend_Loader::loadClass($class);\r
293 $cacheFile = dirname(__FILE__) . '/xmlrpc.cache';\r
294 $server = new Zend_XmlRpc_Server();\r
296 if (!Zend_XmlRpc_Server_Cache::get($cacheFile, $server)) {\r
297     require_once 'My/Services/Glue.php';\r
298     require_once 'My/Services/Paste.php';\r
299     require_once 'My/Services/Tape.php';\r
301     $server->setClass('My_Services_Glue', 'glue');   // пространство имен glue\r
302     $server->setClass('My_Services_Paste', 'paste'); // пространство имен paste\r
303     $server->setClass('My_Services_Tape', 'tape');   // пространство имен tape\r
305     Zend_XmlRpc_Server_Cache::save($cacheFile, $server);\r
308 echo $server->handle();\r
309 ]]></programlisting>\r
310         <para>\r
311             В этом примере производится попытка получить определение сервера из\r
312             файла xmlrpc.cache, находящегося в той же директории, что и скрипт.\r
313             Если попытка не удалась, то загружаются нужные классы и\r
314             прикрепляются к экземпляру сервера, затем создается новый файл кэша\r
315             с определением сервера.\r
316         </para>\r
317     </sect2>\r
319     <sect2 id="zend.xmlrpc.server.use">\r
320         <title>Примеры использования</title>\r
321         <para>\r
322             Здесь приведены несколько примеров использования, демонстрирующих полный\r
323             набор возможностей, доступных разработчикам. Примеры\r
324             построены на основе предоставленных ранее примеров.\r
325         </para>\r
326         <sect3 id="zend.xmlrpc.server.use.case1">\r
327             <title>Основы использования</title>\r
329             <para>\r
330                 В примере ниже прикрепляется функция в качестве\r
331                 доступного для диспетчеризации XML-RPC метода и обрабатываются\r
332                 входящие вызовы.\r
333             </para>\r
335             <programlisting language="php"><![CDATA[\r
336 /**\r
337  * Возвращает сумму MD5 переданного значения\r
338  *\r
339  * @param string $value Value to md5sum\r
340  * @return string MD5 sum of value\r
341  */\r
342 function md5Value($value)\r
344     return md5($value);\r
347 $server = new Zend_XmlRpc_Server();\r
348 $server->addFunction('md5Value');\r
349 echo $server->handle();\r
350 ]]></programlisting>\r
351         </sect3>\r
353         <sect3 id="zend.xmlrpc.server.use.case2">\r
354             <title>Прикрепление класса</title>\r
356             <para>\r
357                 Пример ниже иллюстрирует прикрепление открытых методов класса\r
358                 в качестве доступных для диспетчеризации XML-RPC методов.\r
359             </para>\r
361             <programlisting language="php"><![CDATA[\r
362 require_once 'Services/Comb.php';\r
364 $server = new Zend_XmlRpc_Server();\r
365 $server->setClass('Services_Comb');\r
366 echo $server->handle();\r
367 ]]></programlisting>\r
368         </sect3>\r
370         <sect3 id="zend.xmlrpc.server.use.case3">\r
371             <title>Прикрепление нескольких классов с использованием пространств имен</title>\r
373             <para>\r
374                 Пример ниже демонстрирует прикрепление нескольких классов,\r
375                 каждый со своим пространством имен.\r
376             </para>\r
378             <programlisting language="php"><![CDATA[\r
379 require_once 'Services/Comb.php';\r
380 require_once 'Services/Brush.php';\r
381 require_once 'Services/Pick.php';\r
383 $server = new Zend_XmlRpc_Server();\r
384 $server->setClass('Services_Comb', 'comb');   // методы, вызываемые как comb.*\r
385 $server->setClass('Services_Brush', 'brush'); // методы, вызываемые как brush.*\r
386 $server->setClass('Services_Pick', 'pick');   // методы, вызываемые как pick.*\r
387 echo $server->handle();\r
388 ]]></programlisting>\r
389         </sect3>\r
391         <sect3 id="zend.xmlrpc.server.use.case4">\r
392             <title>Указание исключений в качестве используемых для ответов с сообщением об ошибке</title>\r
394             <para>\r
395                 Пример ниже позволяет любым наследующим от\r
396                 <code>Services_Exception</code>\r
397                 классам предоставлять свои коды и сообщения для подстановки в\r
398                 ответ с сообщением об ошибке.\r
399             </para>\r
401             <programlisting language="php"><![CDATA[\r
402 require_once 'Services/Exception.php';\r
403 require_once 'Services/Comb.php';\r
404 require_once 'Services/Brush.php';\r
405 require_once 'Services/Pick.php';\r
407 // Allow Services_Exceptions to report as fault responses\r
408 Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');\r
410 $server = new Zend_XmlRpc_Server();\r
411 $server->setClass('Services_Comb', 'comb');   // методы, вызываемые как comb.*\r
412 $server->setClass('Services_Brush', 'brush'); // методы, вызываемые как brush.*\r
413 $server->setClass('Services_Pick', 'pick');   // методы, вызываемые как pick.*\r
414 echo $server->handle();\r
415 ]]></programlisting>\r
416         </sect3>\r
418         <sect3 id="zend.xmlrpc.server.use.case5">\r
419             <title>Использование своих объектов запроса</title>\r
421             <para>\r
422                 В примере ниже инстанцируется специальный объект запроса и\r
423                 передается серверу для обработки.\r
424             </para>\r
426             <programlisting language="php"><![CDATA[\r
427 require_once 'Services/Request.php';\r
428 require_once 'Services/Exception.php';\r
429 require_once 'Services/Comb.php';\r
430 require_once 'Services/Brush.php';\r
431 require_once 'Services/Pick.php';\r
433 // Включение Services_Exceptions в список разрешенных исключений\r
434 Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');\r
436 $server = new Zend_XmlRpc_Server();\r
437 $server->setClass('Services_Comb', 'comb');   // методы, вызываемые как comb.*\r
438 $server->setClass('Services_Brush', 'brush'); // методы, вызываемые как brush.*\r
439 $server->setClass('Services_Pick', 'pick');   // методы, вызываемые как pick.*\r
441 // Создание объекта запроса\r
442 $request = new Services_Request();\r
444 echo $server->handle($request);\r
445 ]]></programlisting>\r
446         </sect3>\r
448         <sect3 id="zend.xmlrpc.server.use.case6">\r
449             <title>Использование своих объектов ответа</title>\r
451             <para>\r
452                 Пример ниже демонстрирует указание специального класса ответа\r
453                 для возвращаемого ответа.\r
454             </para>\r
456             <programlisting language="php"><![CDATA[\r
457 require_once 'Services/Request.php';\r
458 require_once 'Services/Response.php';\r
459 require_once 'Services/Exception.php';\r
460 require_once 'Services/Comb.php';\r
461 require_once 'Services/Brush.php';\r
462 require_once 'Services/Pick.php';\r
464 // Включение Services_Exceptions в список разрешенных исключений\r
465 Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');\r
467 $server = new Zend_XmlRpc_Server();\r
468 $server->setClass('Services_Comb', 'comb');   // методы, вызываемые как comb.*\r
469 $server->setClass('Services_Brush', 'brush'); // методы, вызываемые как brush.*\r
470 $server->setClass('Services_Pick', 'pick');   // методы, вызываемые как pick.*\r
472 // Создание объекта запроса\r
473 $request = new Services_Request();\r
475 // Установка другого класса ответа\r
476 $server->setResponseClass('Services_Response');\r
478 echo $server->handle($request);\r
479 ]]></programlisting>\r
480         </sect3>\r
482         <sect3 id="zend.xmlrpc.server.use.case7">\r
483             <title>Кэширование определений сервера между запросами</title>\r
485             <para>\r
486                 Пример ниже демонстрирует кэширование определений сервера между\r
487                 запросами.\r
488             </para>\r
490             <programlisting language="php"><![CDATA[\r
491 // Указание файла кэша\r
492 $cacheFile = dirname(__FILE__) . '/xmlrpc.cache';\r
494 // Включение Services_Exceptions в список разрешенных исключений\r
495 Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');\r
497 $server = new Zend_XmlRpc_Server();\r
499 // Попытка получить определение сервера из кэша\r
500 if (!Zend_XmlRpc_Server_Cache::get($cacheFile, $server)) {\r
501     $server->setClass('Services_Comb', 'comb');   // методы, вызываемые как comb.*\r
502     $server->setClass('Services_Brush', 'brush'); // методы, вызываемые как brush.*\r
503     $server->setClass('Services_Pick', 'pick');   // методы, вызываемые как pick.*\r
505     // Сохранение в кэш\r
506     Zend_XmlRpc_Server_Cache::save($cacheFile, $server);\r
509 // Создание объекта запроса\r
510 $request = new Services_Request();\r
512 // Установка другого класса ответа\r
513 $server->setResponseClass('Services_Response');\r
515 echo $server->handle($request);\r
516 ]]></programlisting>\r
517         </sect3>\r
518     </sect2>\r
519 </sect1>\r
520 <!--\r
521 vim:se ts=4 sw=4 et:\r
522 -->\r