Zend_XmlRpc_Server.xml 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 17175 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.xmlrpc.server">
  5. <title>Zend_XmlRpc_Server</title>
  6. <sect2 id="zend.xmlrpc.server.introduction">
  7. <title>Einführung</title>
  8. <para>
  9. <classname>Zend_XmlRpc_Server</classname> ist als vollständiger
  10. <acronym>XML</acronym>-RPC Server geplant, der den <ulink
  11. url="http://www.xmlrpc.com/spec">Spezifikationen auf www.xmlrpc.com</ulink> folgt.
  12. Des Weiteren implementiert er die Methode system.multicall(), welche dem Entwickler
  13. erlaubt, mehrere Anfragen aufzureihen.
  14. </para>
  15. </sect2>
  16. <sect2 id="zend.xmlrpc.server.usage">
  17. <title>Grundlegende Benutzung</title>
  18. <para>
  19. Ein Beispiel der grundlegendsten Benutzung:
  20. </para>
  21. <programlisting language="php"><![CDATA[
  22. $server = new Zend_XmlRpc_Server();
  23. $server->setClass('My_Service_Class');
  24. echo $server->handle();
  25. ]]></programlisting>
  26. </sect2>
  27. <sect2 id="zend.xmlrpc.server.structure">
  28. <title>Server-Struktur</title>
  29. <para>
  30. <classname>Zend_XmlRpc_Server</classname> ist aus einer Vielfalt von Komponenten
  31. zusammengesetzt, die vom Server selbst über Anfrage-, Antwort- und bis hin zu
  32. Fehler-Objekten reicht.
  33. </para>
  34. <para>
  35. Um den <classname>Zend_XmlRpc_Server</classname> zu erstellen, muss der Entwickler dem
  36. Server eine oder mehrere Klassen oder Funktionen durch die Methoden
  37. <methodname>setClass()</methodname> und <methodname>addFunction()</methodname>
  38. hinzufügen.
  39. </para>
  40. <para>
  41. Wenn dieses erstmal erledigt wurde, kann man entweder der Methode
  42. <methodname>Zend_XmlRpc_Server::handle()</methodname> ein
  43. <classname>Zend_XmlRpc_Request</classname>-Objekt übergeben oder es wird ein
  44. <classname>Zend_XmlRpc_Request_Http</classname> instanziert, falls keines angegeben
  45. wurde - die Anfrage wird also aus <code>php://input</code> geladen.
  46. </para>
  47. <para>
  48. <methodname>Zend_XmlRpc_Server::handle()</methodname> versucht daraufhin, den
  49. zuständigen Handler, der durch die angeforderte Methode bestimmt wird,
  50. auszuführen. Es wird entweder ein <classname>Zend_XmlRpc_Response</classname>-
  51. oder ein <classname>Zend_XmlRpc_Server_Fault</classname>-Objekt zurückgegeben.
  52. Beide Objekte besitzen eine Methode <methodname>__toString()</methodname>, die eine
  53. valide <acronym>XML</acronym>-RPC Antwort im <acronym>XML</acronym>-Format zurückgibt,
  54. die direkt ausgegeben werden kann.
  55. </para>
  56. </sect2>
  57. <sect2 id="zend.xmlrpc.server.conventions">
  58. <title>Konventionen</title>
  59. <para>
  60. <classname>Zend_XmlRpc_Server</classname> ermöglicht es dem Entwickler, Funktionen und
  61. Methodenaufrufe als ausführbare <acronym>XML</acronym>-RPC Methoden anzufügen. Durch
  62. <classname>Zend_Server_Reflection</classname> wird die Überwachung aller angefügten
  63. Methoden - durch Nutzung der DocBlocks der Methoden und Funktionen
  64. werden deren Hilfstexte und Signaturen ermittelt - ermöglicht.
  65. </para>
  66. <para>
  67. <acronym>XML</acronym>-RPC Typen werden nicht zwingend 1:1 zu <acronym>PHP</acronym>
  68. Typen konvertiert. Dennoch wird versucht, einen passenden Typ, anhand der in
  69. @param- und @return-Zeilen enthaltenen Werte, zu ermitteln. Einige
  70. <acronym>XML</acronym>-RPC-Typen besitzen jedoch kein direktes Äquivalent und sollten
  71. deshalb mittels <acronym>PHP</acronym>doc auf einen <acronym>XML</acronym>-RPC-Typen
  72. hinweisen. Diese beinhalten:
  73. </para>
  74. <itemizedlist>
  75. <listitem><para>dateTime.iso8601, ein String, der das Format
  76. YYYYMMDDTHH:mm:ss besitzt</para></listitem>
  77. <listitem><para>base64, base64-kodierte Daten</para></listitem>
  78. <listitem><para>struct, jegliches assoziatives Array</para></listitem>
  79. </itemizedlist>
  80. <para>
  81. 'Anbei ein Beispiel für einen solchen Hinweis:
  82. </para>
  83. <programlisting language="php"><![CDATA[
  84. /**
  85. * Dies ist eine Beispielfunktion.
  86. *
  87. * @param base64 $val1 Base64-kodierte Daten
  88. * @param dateTime.iso8601 $val2 Ein ISO-Datum
  89. * @param struct $val3 ein assoziatives Array
  90. * @return struct
  91. */
  92. function myFunc($val1, $val2, $val3)
  93. {
  94. }
  95. ]]></programlisting>
  96. <para>
  97. PhpDocumentor validiert keine Typen, die in Parameter- oder
  98. Rückgabewerten angegeben sind, weshalb dies keinen Einfluss auf
  99. die <acronym>API</acronym> Dokumentation hat. Das Angeben der Hinweise ist notwendig,
  100. da der Server die, dem Methodenaufruf zugewiesenen, Parameter
  101. validiert.
  102. </para>
  103. <para>
  104. Es ist genauso gut möglich, mehrere Werte als Parameter oder für
  105. die Rückgabe anzugeben; die <acronym>XML</acronym>-RPC Spezifikation schlägt sogar
  106. vor, dass system.methodeSignatur ein Array, das alle möglichen
  107. Methodensignaturen (d.h. jegliche Kombination aus Parametern und
  108. Rückgabewerten) enthält, zurückgibt. Um dies zu erreichen, kann
  109. man, wie man es normalerweise auch beim PhpDocumentor auch tun würde,
  110. einfach den '|'-Operator nutzen.
  111. </para>
  112. <programlisting language="php"><![CDATA[
  113. /**
  114. * Dies ist eine Beispiel-Funktion.
  115. *
  116. * @param string|base64 $val1 String oder base64-kodierte Daten
  117. * @param string|dateTime.iso8601 $val2 String oder ein ISO-Datum
  118. * @param array|struct $val3 Normal indiziertes oder assoziatives Array
  119. * @return boolean|struct
  120. */
  121. function myFunc($val1, $val2, $val3)
  122. {
  123. }
  124. ]]></programlisting>
  125. <para>
  126. Dennoch eine Anmerkung: Das Erlaubung von vielen Signaturen kann
  127. zu Verwirrung für Entwickler führen, die diese Services nutzen;
  128. man sollte einer <acronym>XML</acronym>-RPC Methode deshalb nur eine Signatur zuweisen.
  129. </para>
  130. </sect2>
  131. <sect2 id="zend.xmlrpc.server.namespaces">
  132. <title>Nutzen von Namensräumen</title>
  133. <para>
  134. <acronym>XML</acronym>-RPC besitzt ein Konzept für Namensräume; Grundlegend erlaubt es
  135. das Gruppieren von <acronym>XML</acronym>-RPC-Methoden durch Punkt-separierte
  136. Namensräume. Dies hilft, Namenkollisionen zwischen Methoden, die durch verschiedene
  137. Klassen offeriert werden, zu verhindern. Beispielsweise kann der
  138. <acronym>XML</acronym>-RPC-Server mehrere Methoden im 'system'-Namensraum nutzen:
  139. </para>
  140. <itemizedlist>
  141. <listitem><para>system.listMethods</para></listitem>
  142. <listitem><para>system.methodHelp</para></listitem>
  143. <listitem><para>system.methodSignature</para></listitem>
  144. </itemizedlist>
  145. <para>
  146. Intern werden die Methoden zu Methoden desselben Namens in der
  147. Klasse <classname>Zend_XmlRpc_Server</classname> umgeleitet.
  148. </para>
  149. <para>
  150. Um angebotenen Methoden Namensräume hinzuzufügen, muss man lediglich beim
  151. Hinzufügen der gewünschten Klasse oder Funktion einen Namensraum angeben:
  152. </para>
  153. <programlisting language="php"><![CDATA[
  154. // Alle öffentlichten Methoden in My_Service_Class sind als
  155. // myservice.METHODNAME verfügbar
  156. $server->setClass('My_Service_Class', 'myservice');
  157. // Funktion 'somefunc' ist als funcs.somefunc ansprechbar.
  158. $server->addFunction('somefunc', 'funcs');
  159. ]]></programlisting>
  160. </sect2>
  161. <sect2 id="zend.xmlrpc.server.request">
  162. <title>Eigene Request-Objekte</title>
  163. <para>
  164. Die meiste Zeit wird man einfach den Standard-Anfragetyp
  165. <classname>Zend_XmlRpc_Request_Http</classname>, welcher im
  166. <classname>Zend_XmlRpc_Server</classname> enthalten ist, nutzen. Jedoch gibt es
  167. gelegentlich Fälle, in denen <acronym>XML</acronym>-RPC über die Kommandozeile (CLI),
  168. ein grafisches Benutzerinterface (GUI), eine andere Umgebung oder beim Protokollieren
  169. von ankommenden Anfragen erreichbar sein muss. Um dies zu bewerkstelligen, muss man ein
  170. eigenes Anfrage-Objekt kreieren, das <classname>Zend_XmlRpc_Request</classname>
  171. erweitert. Die wichtigste Sache, die man sich merken muss, ist sicherzustellen, dass die
  172. Methoden getMethod() und getParams() implementiert sind, so dass der
  173. <acronym>XML</acronym>-RPC-Server Informationen erhält, die er für das Abfertigen einer
  174. Anfrage benötigt.
  175. </para>
  176. </sect2>
  177. <sect2 id="zend.xmlrpc.server.response">
  178. <title>Eigene Antwort-Objekte</title>
  179. <para>
  180. Ähnlich wie bei den Anfrage-Objekten, kann der <classname>Zend_XmlRpc_Server</classname>
  181. auch eigene Antwortobjekte ausliefern; standardmäßig ist dies ein
  182. <classname>Zend_XmlRpc_Response_Http-Objekt</classname>, das einen passenden
  183. Content-Type <acronym>HTTP</acronym>-Header sendet, der für <acronym>XML</acronym>-RPC
  184. genutzt wird. Mögliche Nutzungen eines eigenen Objekts sind z.B. das Protokollieren von
  185. Antworten oder das Senden der Antworten zu STDOUT.
  186. </para>
  187. <para>
  188. Um eine eigene Antwortklasse zu nutzen, muss
  189. <methodname>Zend_XmlRpc_Server::setResponseClass()</methodname> vor dem Aufruf von
  190. <methodname>handle()</methodname> aufgerufen werden.
  191. </para>
  192. </sect2>
  193. <sect2 id="zend.xmlrpc.server.fault">
  194. <title>Verarbeiten von Exceptions durch Fehler</title>
  195. <para>
  196. <classname>Zend_XmlRpc_Server</classname> fängt die, durch eine ausgeführte Methode
  197. erzeugten, Exceptions and generiert daraus einen <acronym>XML</acronym>-RPC-Fehler als
  198. Antwort, wenn eine Exception gefangen wurde. Normalerweise werden die
  199. Exceptionnachrichten und -codes nicht in der Fehler-Antwort genutzt. Dies ist eine
  200. gewollte Entscheidung um den Code zu schützen; viele Exceptions entblößen mehr
  201. Informationen über den Code oder die Umgebung als der Entwickler
  202. wünscht (ein Paradebeispiel beinhaltet Datenbankabstraktion- oder
  203. die Zugriffsschichten-Exceptions).
  204. </para>
  205. <para>
  206. Exception-Klassen können jedoch anhand einer Weißliste (Whitelist) als
  207. Fehler-Antworten zurückgegeben werden. Dazu muss man lediglich die gewünschte
  208. Exception mittels
  209. <methodname>Zend_XmlRpc_Server_Fault::attachFaultException()</methodname> zur
  210. Weißliste hinzufügen:
  211. </para>
  212. <programlisting language="php"><![CDATA[
  213. Zend_XmlRpc_Server_Fault::attachFaultException('My_Project_Exception');
  214. ]]></programlisting>
  215. <para>
  216. Abgeleitete Exceptions lassen sich als ganze Familie von Exceptions
  217. hinzufügen, indem man deren Basisklasse angibt.
  218. <classname>Zend_XmlRpc_Server_Exception</classname>'s sind immer auf der Weißliste zu
  219. finden, da sie spezielle Serverfehler berichten (undefinierte Methoden, etc.).
  220. </para>
  221. <para>
  222. Jede Exception, die nicht auf der Weißliste zu finden ist, generiert
  223. eine Antwort mit dem '404' Code und der Nachricht 'Unknown error'.
  224. </para>
  225. </sect2>
  226. <sect2 id="zend.xmlrpc.server.caching">
  227. <title>Zwischenspeichern von Serverdefinitionen zwischen den Anfragen</title>
  228. <para>
  229. Das Hinzufügen einer Vielzahl von Klassen zu einer <acronym>XML</acronym>-RPC-Server
  230. Instanz kann zu einem großen Ressourcenverbrauch führen; jede Klasse muss via Reflection
  231. <acronym>API</acronym> (<classname>Zend_Server_Reflection</classname>) inspiziert
  232. werden, welche eine Liste von allen möglichen Signaturen, die der Server verwenden kann,
  233. zurückgibt.
  234. </para>
  235. <para>
  236. Um die Einbußen zu reduzieren, kann <classname>Zend_XmlRpc_Server_Cache</classname>
  237. genutzt werden, welche die Serverdefinitionen zwischen den Anfragen zwischenspeichert.
  238. Wenn dies mit __autoload() kombiniert wird, kann es zu einem großen
  239. Geschwindigkeitsschub kommen.
  240. </para>
  241. <para>
  242. Ein Beispiel folgt:
  243. </para>
  244. <programlisting language="php"><![CDATA[
  245. function __autoload($class)
  246. {
  247. Zend_Loader::loadClass($class);
  248. }
  249. $cacheFile = dirname(__FILE__) . '/xmlrpc.cache';
  250. $server = new Zend_XmlRpc_Server();
  251. if (!Zend_XmlRpc_Server_Cache::get($cacheFile, $server)) {
  252. require_once 'My/Services/Glue.php';
  253. require_once 'My/Services/Paste.php';
  254. require_once 'My/Services/Tape.php';
  255. $server->setClass('My_Services_Glue', 'glue'); // glue. Namensraum
  256. $server->setClass('My_Services_Paste', 'paste'); // paste. Namensraum
  257. $server->setClass('My_Services_Tape', 'tape'); // tape. Namensraum
  258. Zend_XmlRpc_Server_Cache::save($cacheFile, $server);
  259. }
  260. echo $server->handle();
  261. ]]></programlisting>
  262. <para>
  263. Obiges Beispiel zeigt, wie der Server versucht, eine Definition
  264. aus der Datei xmlrpc.cache, welches sich im selben Ordner wie das
  265. Skript befindet, zu laden. Wenn dies nicht erfolgreich ist,
  266. lädt es die Server-Klassen, die es benötigt, und fügt sie zum
  267. Server hinzu. Danach wird versucht, die Cache-Datei mit der
  268. Serverdefinition zu erstellen.
  269. </para>
  270. </sect2>
  271. <sect2 id="zend.xmlrpc.server.use">
  272. <title>Nutzungsbeispiele</title>
  273. <para>
  274. Unten finden sich etliche Beispiele für eine Nutzung, die das
  275. gesamte Spektrum der verfügbaren Optionen für den Entwickler darstellen.
  276. These Beispiele bauen immer auf den vorangegangenen Beispielen auf.
  277. </para>
  278. <sect3 id="zend.xmlrpc.server.use.case1">
  279. <title>Grundlegende Benutzung</title>
  280. <para>
  281. Folgendes Beispiel fügt eine Funktion als ausführbare
  282. <acronym>XML</acronym>-RPC-Methode hinzu und verarbeitet eingehende Aufrufe.
  283. </para>
  284. <programlisting language="php"><![CDATA[
  285. /**
  286. * Gibt die MD5-Summe eines Strings zurück.
  287. *
  288. * @param string $value Wert aus dem die MD5-Summe errechnet wird
  289. * @return string MD5-Summe des Werts
  290. */
  291. function md5Value($value)
  292. {
  293. return md5($value);
  294. }
  295. $server = new Zend_XmlRpc_Server();
  296. $server->addFunction('md5Value');
  297. echo $server->handle();
  298. ]]></programlisting>
  299. </sect3>
  300. <sect3 id="zend.xmlrpc.server.use.case2">
  301. <title>Hinzufügen einer Klasse</title>
  302. <para>
  303. Das nächste Beispiel illustriert, wie man die öffentlichen Methoden
  304. eienr Klasse als ausführbare <acronym>XML</acronym>-RPC-Methoden hinzufügt.
  305. </para>
  306. <programlisting language="php"><![CDATA[
  307. $server = new Zend_XmlRpc_Server();
  308. $server->setClass('Services_Comb');
  309. echo $server->handle();
  310. ]]></programlisting>
  311. </sect3>
  312. <sect3 id="zend.xmlrpc.server.use.case3">
  313. <title>Mehrere Klassen unter der Nutzung von Namensräumen hinzufügen</title>
  314. <para>
  315. Das nächste Beispiel zeigt, wie man mehrer Klassen mit ihren eigenen
  316. Namensräumen hinzufügt.
  317. </para>
  318. <programlisting language="php"><![CDATA[
  319. require_once 'Services/Comb.php';
  320. require_once 'Services/Brush.php';
  321. require_once 'Services/Pick.php';
  322. $server = new Zend_XmlRpc_Server();
  323. // Methoden werden als comb.* aufgerufen
  324. $server->setClass('Services_Comb', 'comb');
  325. // Methoden werden als brush.* aufgerufen
  326. $server->setClass('Services_Brush', 'brush');
  327. // Methoden werden als pick.* aufgerufen
  328. $server->setClass('Services_Pick', 'pick');
  329. echo $server->handle();
  330. ]]></programlisting>
  331. </sect3>
  332. <sect3 id="zend.xmlrpc.server.use.case4">
  333. <title>Bestimmen von Exceptions als valide Fehler-Antwort</title>
  334. <para>
  335. Im nächsten Beispiel wird gezeigt, wie man jede Exception, die von
  336. <classname>Services_Exception</classname> abgeleitet wurde, als Fehler-Antwort
  337. nutzen kann, dessen Nachricht und Code erhalten bleibt.
  338. </para>
  339. <programlisting language="php"><![CDATA[
  340. require_once 'Services/Exception.php';
  341. require_once 'Services/Comb.php';
  342. require_once 'Services/Brush.php';
  343. require_once 'Services/Pick.php';
  344. // Services_Exceptions dürfen als Fehler-Antwort genutzt werden
  345. Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');
  346. $server = new Zend_XmlRpc_Server();
  347. // Methoden werden als comb.* aufgerufen
  348. $server->setClass('Services_Comb', 'comb');
  349. // Methoden werden als brush.* aufgerufen
  350. $server->setClass('Services_Brush', 'brush');
  351. // Methoden werden als pick.* aufgerufen
  352. $server->setClass('Services_Pick', 'pick');
  353. echo $server->handle();
  354. ]]></programlisting>
  355. </sect3>
  356. <sect3 id="zend.xmlrpc.server.use.case5">
  357. <title>Nutzen eines eigenen Anfrage-Objekts</title>
  358. <para>
  359. Im folgenden Beispiel wird ein eigenes Anfrage-Objekt instanziert
  360. und durch den Server verarbeitet.
  361. </para>
  362. <programlisting language="php"><![CDATA[
  363. require_once 'Services/Request.php';
  364. require_once 'Services/Exception.php';
  365. require_once 'Services/Comb.php';
  366. require_once 'Services/Brush.php';
  367. require_once 'Services/Pick.php';
  368. // Services_Exceptions dürfen als Fehler-Antwort genutzt werden
  369. Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');
  370. $server = new Zend_XmlRpc_Server();
  371. // Methoden werden als comb.* aufgerufen
  372. $server->setClass('Services_Comb', 'comb');
  373. // Methoden werden als brush.* aufgerufen
  374. $server->setClass('Services_Brush', 'brush');
  375. // Methoden werden als pick.* aufgerufen
  376. $server->setClass('Services_Pick', 'pick');
  377. // Ein neues Anfrage-Objekt wird erstellt
  378. $request = new Services_Request();
  379. echo $server->handle($request);
  380. ]]></programlisting>
  381. </sect3>
  382. <sect3 id="zend.xmlrpc.server.use.case6">
  383. <title>Nutzen eigener Antwort-Objekte</title>
  384. <para>
  385. Das nachstehende Beispiel zeigt, wie man eine eigene Antwort-Klasse
  386. als zurückgegebene Antwort für den Server setzt.
  387. </para>
  388. <programlisting language="php"><![CDATA[
  389. require_once 'Services/Request.php';
  390. require_once 'Services/Response.php';
  391. require_once 'Services/Exception.php';
  392. require_once 'Services/Comb.php';
  393. require_once 'Services/Brush.php';
  394. require_once 'Services/Pick.php';
  395. // Services_Exceptions dürfen als Fehler-Antwort genutzt werden
  396. Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');
  397. $server = new Zend_XmlRpc_Server();
  398. // Methoden werden als comb.* aufgerufen
  399. $server->setClass('Services_Comb', 'comb');
  400. // Methoden werden als brush.* aufgerufen
  401. $server->setClass('Services_Brush', 'brush');
  402. // Methoden werden als pick.* aufgerufen
  403. $server->setClass('Services_Pick', 'pick');
  404. // Ein neues Anfrage-Objekt wird erstellt
  405. $request = new Services_Request();
  406. // Nutzen eigener Antwort-Klasse
  407. $server->setResponseClass('Services_Response');
  408. echo $server->handle($request);
  409. ]]></programlisting>
  410. </sect3>
  411. <sect3 id="zend.xmlrpc.server.use.case7">
  412. <title>Zwischenspeichern von Serverdefinition zwischen den Anfragen</title>
  413. <para>
  414. Dieses Beispiel zeigt, wie man Serverdefinitionen zwischen verschiedenen
  415. Anfragen zwischenspeichern kann.
  416. </para>
  417. <programlisting language="php"><![CDATA[
  418. // Definieren einer Cache-Datei
  419. $cacheFile = dirname(__FILE__) . '/xmlrpc.cache';
  420. // Services_Exceptions dürfen als Fehler-Antwort genutzt werden
  421. Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');
  422. $server = new Zend_XmlRpc_Server();
  423. // Versucht die Serverdefinition aus dem Cache zu laden
  424. if (!Zend_XmlRpc_Server_Cache::get($cacheFile, $server)) {
  425. // Methoden werden als comb.* aufgerufen
  426. $server->setClass('Services_Comb', 'comb');
  427. // Methoden werden als brush.* aufgerufen
  428. $server->setClass('Services_Brush', 'brush');
  429. // Methoden werden als pick.* aufgerufen
  430. $server->setClass('Services_Pick', 'pick');
  431. // Speichern des Caches
  432. Zend_XmlRpc_Server_Cache::save($cacheFile, $server);
  433. }
  434. // Ein neues Anfrage-Objekt wird erstellt
  435. $request = new Services_Request();
  436. // Nutzen eigener Antwort-Klasse
  437. $server->setResponseClass('Services_Response');
  438. echo $server->handle($request);
  439. ]]></programlisting>
  440. </sect3>
  441. </sect2>
  442. </sect1>
  443. <!--
  444. vim:se ts=4 sw=4 et:
  445. -->