| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.xmlrpc.server">
- <title>Zend_XmlRpc_Server</title>
- <sect2 id="zend.xmlrpc.server.introduction">
- <title>Introduction</title>
- <para>
- <classname>Zend_XmlRpc_Server</classname> fournit un serveur XML-RPC qui suit les
- spécifications <ulink url="http://www.xmlrpc.com/spec">dictées par
- www.xmlrpc.com</ulink>. Il fournit aussi la méthode <code>system.multicall()</code>,
- permettant le traitement de requêtes multiples.
- </para>
- </sect2>
- <sect2 id="zend.xmlrpc.server.usage">
- <title>Usage de base</title>
- <para>Voici un exemple d'utilisation basique :</para>
- <programlisting language="php"><![CDATA[
- $server = new Zend_XmlRpc_Server();
- $server->setClass('My_Service_Class');
- echo $server->handle();
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.xmlrpc.server.structure">
- <title>Structures du serveur</title>
- <para>
- <classname>Zend_XmlRpc_Server</classname> se décompose en un objet serveur
- (lui-même), un objet requête, réponse, et des objets d'erreurs.
- </para>
- <para>
- Pour démarrer un serveur <classname>Zend_XmlRpc_Server</classname>, vous devez
- attacher une ou plusieurs classes ou fonctions au serveur, grâce à
- <methodname>setClass()</methodname> et <methodname>addFunction()</methodname>.
- </para>
- <para>
- Lorsque c'est fait, vous pouvez passer un objet
- <classname>Zend_XmlRpc_Request</classname> à
- <methodname>Zend_XmlRpc_Server::handle()</methodname>, sinon par défaut il utilisera un
- objet <classname>Zend_XmlRpc_Request_Http</classname> qui récupérera la requête depuis
- <code>php://input</code>.
- </para>
- <para>
- <methodname>Zend_XmlRpc_Server::handle()</methodname> va alors essayer de traiter la
- requête. Cette méthode retournera un objet <classname>Zend_XmlRpc_Response</classname>
- ou <classname>Zend_XmlRpc_Server_Fault</classname>. Tous deux possèdent une méthode
- <methodname>__toString()</methodname> qui crée une réponse <acronym>XML</acronym> valide XML-RPC.
- </para>
- </sect2>
- <sect2 id="zend.xmlrpc.server.anatomy">
- <title>Anatomy of a webservice</title>
- <sect3 id="zend.xmlrpc.server.anatomy.general">
- <title>General considerations</title>
- <para>
- For maximum performance it is recommended to use a simple
- bootstrap file for the server component. Using
- <classname>Zend_XmlRpc_Server</classname> inside a
- <link linkend="zend.controller"><classname>Zend_Controller</classname></link>
- is strongly discouraged to avoid the overhead.
- </para>
- <para>
- Services change over time and while webservices are generally
- less change intense as code-native <acronym>APIs</acronym>, it
- is recommended to version your service. Do so to lay grounds to
- provide compatibility for clients using older versions of your
- service and manage your service lifecycle including deprecation
- timeframes.To do so just include a version number into your
- <acronym>URI</acronym>. It is also recommended to include the
- remote protocol name in the <acronym>URI</acronym> to allow easy
- integration of upcoming remoting technologies.
- http://myservice.ws/<emphasis>1.0/XMLRPC/</emphasis>.
- </para>
- </sect3>
- <sect3 id="zend.xmlrpc.server.anatomy.expose">
- <title>What to expose?</title>
- <para>
- Most of the time it is not sensible to expose business objects
- directly. Business objects are usually small and under heavy
- change, because change is cheap in this layer of your
- application. Once deployed and adopted, web services are hard to
- change. Another concern is <acronym>I/O</acronym> and latency:
- the best webservice calls are those not happening. Therefore
- service calls need to be more coarse-grained than usual business
- logic is. Often an additional layer in front of your business
- objects makes sense. This layer is sometimes referred to as
- <ulink url="http://martinfowler.com/eaaCatalog/remoteFacade.html">Remote Facade.</ulink>.
- Such a service layer adds a coarse grained interface on top of
- your business logic and groups verbose operations into smaller
- ones.
- </para>
- </sect3>
- </sect2>
- <sect2 id="zend.xmlrpc.server.conventions">
- <title>Conventions</title>
- <para>
- <classname>Zend_XmlRpc_Server</classname> permet d'attacher des classes et/ou des
- fonctions au serveur XML-RPC. Grâce à <classname>Zend_Server_Reflection</classname>,
- l'introspection va utiliser les blocs de commentaires pour déterminer les types
- d'arguments et de réponse de la fonction/classe.
- </para>
- <para>
- Les types XML-RPC n'ont pas forcément de correspondance native vers un type <acronym>PHP</acronym>.
- Le code fera de son mieux pour deviner le type de données approprié, en se basant sur
- les valeurs listées dans les balises @param et @return. Certains types XML-RPC n'ont par
- contre pas d'équivalent <acronym>PHP</acronym> direct, ils devront alors être spécifiés manuellement sous
- forme de balises phpdoc :
- </para>
- <itemizedlist>
- <listitem>
- <para>dateTime.iso8601, une chaîne formatée comme YYYYMMDDTHH:mm:ss</para>
- </listitem>
- <listitem>
- <para>base64, données encodées en base64</para>
- </listitem>
- <listitem>
- <para>struct, tableau associatif</para>
- </listitem>
- </itemizedlist>
- <para>Voici un exemple d'utilisation de type particulier:</para>
- <programlisting language="php"><![CDATA[
- /**
- * This is a sample function
- *
- * @param base64 $val1 Base64-encoded data
- * @param dateTime.iso8601 $val2 An ISO date
- * @param struct $val3 An associative array
- * @return struct
- */
- function myFunc($val1, $val2, $val3)
- {}
- ]]></programlisting>
- <para>
- PhpDocumentor ne vérifie (valide) pas les types des paramètres, mais les types
- sont obligatoires pour que le serveur puisse lui, valider les paramètres passés aux
- appels des méthodes.
- </para>
- <para>
- Il est parfaitement valide de spécifier plusieurs types pour les paramètres et les
- retours de méthodes. La spécification XML-RPC suggère que system.methodSignature
- retourne un tableau des possibilités au regard des paramètres d'entrée de la méthode, et
- de son type de sortie. Ceci ce fait grâce au caractère '|' de PhpDocumentor
- </para>
- <programlisting language="php"><![CDATA[
- /**
- * This is a sample function
- *
- * @param string|base64 $val1 String or base64-encoded data
- * @param string|dateTime.iso8601 $val2 String or an ISO date
- * @param array|struct $val3 Normal indexed array or an associative array
- * @return boolean|struct
- */
- function myFunc($val1, $val2, $val3)
- {}
- ]]></programlisting>
- <note>
- <para>
- Attention toutefois, une signature multiple peut prêter à confusion au regard des
- personnes utilisant votre service. En général une fonction ne devrait posséder qu'une
- seule signature.
- </para>
- </note>
- </sect2>
- <sect2 id="zend.xmlrpc.server.namespaces">
- <title>Utiliser des espaces de noms (Namespaces)</title>
- <para>
- XML-RPC accepte le concept d'espace de noms, ce qui permet de grouper les méthodes
- XML-RPC. Ceci aide à prévenir les collisions de noms (deux fonctions avec le même nom),
- de différentes classes. Par exemple le serveur XML-RPC sert des méthodes dans l'espace
- "system" :
- </para>
- <itemizedlist>
- <listitem>
- <para>system.listMethods</para>
- </listitem>
- <listitem>
- <para>system.methodHelp</para>
- </listitem>
- <listitem>
- <para>system.methodSignature</para>
- </listitem>
- </itemizedlist>
- <para>
- En interne la correspondance est faite avec les méthodes du même nom, de
- <classname>Zend_XmlRpc_Server</classname>.
- </para>
- <para>
- Si vous voulez ajouter un espace de noms aux méthodes que vous servez, procédez
- alors comme suit :
- </para>
- <programlisting language="php"><![CDATA[
- // Toutes les méthodes publiques de My_Service_Class seront accessibles
- // via myservice.METHODNAME
- $server->setClass('My_Service_Class', 'myservice');
- // la fonction 'somefunc' sera accessible via funcs.somefunc
- $server->addFunction('somefunc', 'funcs');
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.xmlrpc.server.request">
- <title>Requêtes personnalisées</title>
- <para>
- La plupart du temps, vous utiliserez l'objet de requête par défaut
- <classname>Zend_XmlRpc_Request_Http</classname>, sans vous en occuper. En revanche si
- vous avez un besoin spécifique, comme par exemple journaliser la requête, traiter une
- requête CLI, GUI, ou autre environnement, vous devrez alors créer un objet étendant
- <classname>Zend_XmlRpc_Request</classname>. Implémentez les méthodes
- <methodname>getMethod()</methodname> et <methodname>getParams()</methodname> afin que le serveur puisse analyser
- ces informations pour traiter la requête.
- </para>
- </sect2>
- <sect2 id="zend.xmlrpc.server.response">
- <title>Réponses personnalisées</title>
- <para>
- Comme avec les objets de requête, <classname>Zend_XmlRpc_Server</classname> peut
- retourner des objets de réponse personnalisés. Par défaut il s'agit d'objets
- <classname>Zend_XmlRpc_Response_Http</classname> qui envoient un en-tête <acronym>HTTP</acronym>
- Content-Type <acronym>HTTP</acronym> pour XML-RPC. Vous pourriez utiliser des objets de réponse
- personnalisés pour par exemple renvoyer les réponses vers STDOUT, ou les
- journaliser.
- </para>
- <para>
- Pour utiliser une classe de réponse personnalisée, utilisez
- <methodname>Zend_XmlRpc_Server::setResponseClass()</methodname> avant d'appeler
- <methodname>handle()</methodname>.
- </para>
- </sect2>
- <sect2 id="zend.xmlrpc.server.fault">
- <title>Gérer les exceptions grâce aux erreurs (Faults)</title>
- <para>
- <classname>Zend_XmlRpc_Server</classname> attrape les Exceptions générées par vos
- classes/fonctions, et génère une réponse XML-RPC "fault" lorsqu'une exception a été
- rencontrée. Par défaut, les message et code des exceptions ne sont pas attachés dans la
- réponse XML-RPC. Ceci est du au fait que de telles exceptions peuvent en dire trop, au
- regard de la sécurité de votre application.
- </para>
- <para>
- Des classes d'exception peuvent cependant être mises en liste blanche, et donc
- utilisées pour les réponses d'erreur ("fault"). Utilisez simplement
- <methodname>Zend_XmlRpc_Server_Fault::attachFaultException()</methodname> en lui passant
- une classe d'exception :
- </para>
- <programlisting language="php"><![CDATA[
- Zend_XmlRpc_Server_Fault::attachFaultException('My_Project_Exception');
- ]]></programlisting>
- <para>
- Si vous héritez correctement vos exceptions, vous pouvez alors passer en liste
- blanche l'exception de plus bas niveau, et ainsi accepter plusieurs types d'exceptions
- qui en hériteront. Évidemment, les Zend_XmlRpc_Server_Exceptions sont elles
- automatiquement mises en liste blanche, afin de pouvoir traiter les requêtes vers des
- méthodes inexistantes, ou toute autre erreur "générique".
- </para>
- <para>
- Toute exception rencontrée, mais non mise en liste blanche, donnera naissance à
- une réponse d'erreur avec le code "404" et le message "Unknown error".
- </para>
- </sect2>
- <sect2 id="zend.xmlrpc.server.caching">
- <title>Cacher la définition du serveur entre les requêtes</title>
- <para>
- Attacher beaucoup de classes au serveur XML-RPC peut consommer beaucoup de
- ressources, car l'introspection de chaque classe/fonction est mise en place.
- </para>
- <para>
- Pour améliorer les performances, <classname>Zend_XmlRpc_Server_Cache</classname>
- peut être utilisé pour mettre en cache la définition d'un serveur. Combiné à
- <methodname>__autoload()</methodname>, ceci améliore grandement les performances.
- </para>
- <para>Un exemple d'utilisation :</para>
- <programlisting language="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');
- // espace de noms glue
- $server->setClass('My_Services_Paste', 'paste');
- // espace de noms paste
- $server->setClass('My_Services_Tape', 'tape');
- // espace de noms tape
- Zend_XmlRpc_Server_Cache::save($cacheFile, $server);
- }
- echo $server->handle();
- ]]></programlisting>
- <para>
- L'exemple ci dessus essaye de récupérer la définition du serveur via le fichier
- <filename>xmlrpc.cache</filename>. Si ceci échoue, alors les classes nécessaires au
- service sont chargées, attachées au serveur, et une tentative de création de cache est
- lancée.
- </para>
- </sect2>
- <sect2 id="zend.xmlrpc.server.use">
- <title>Exemples d'utilisation</title>
- <para>
- Voici quelques exemples qui démontrent les diverses options disponibles pour un
- serveur XML-RPC.
- </para>
- <example id="zend.xmlrpc.server.use.attach-function">
- <title>Utilisation basique</title>
- <para>L'exemple ci dessous attache une fonction au service XML-RPC.</para>
- <programlisting language="php"><![CDATA[
- /**
- * Retourne le hash MD5 d'une valeur
- *
- * @param string $value Valeur à hasher
- * @return string Hash MD5 de la valeur
- */
- function md5Value($value)
- {
- return md5($value);
- }
- $server = new Zend_XmlRpc_Server();
- $server->addFunction('md5Value');
- echo $server->handle();
- ]]></programlisting>
- </example>
- <example id="zend.xmlrpc.server.use.attach-class">
- <title>Attacher une classe</title>
- <para>
- L'exemple ci dessous montre comment attacher les méthodes publiques d'une
- classe en tant que méthodes XML-RPC.
- </para>
- <programlisting language="php"><![CDATA[
- $server = new Zend_XmlRpc_Server();
- $server->setClass('Services_Comb');
- echo $server->handle();
- ]]></programlisting>
- </example>
- <example id="zend.xmlrpc.server.use.attach-class-with-arguments">
- <title>Attaching a class with arguments</title>
- <para>
- The following example illustrates how to attach a class' public
- methods and passing arguments to its methods. This can be used to specify certain
- defaults when registering service classes.
- </para>
- <programlisting language="php"><![CDATA[
- class Services_PricingService
- {
- /**
- * Calculate current price of product with $productId
- *
- * @param ProductRepository $productRepository
- * @param PurchaseRepository $purchaseRepository
- * @param integer $productId
- */
- public function calculate(ProductRepository $productRepository,
- PurchaseRepository $purchaseRepository,
- $productId)
- {
- ...
- }
- }
- $server = new Zend_XmlRpc_Server();
- $server->setClass('Services_PricingService',
- 'pricing',
- new ProductRepository(),
- new PurchaseRepository());
- ]]></programlisting>
- <para>
- The arguments passed at <methodname>setClass()</methodname> at server construction time are
- injected into the method call <command>pricing.calculate()</command> on remote invokation.
- In the example above, only the argument <varname>$purchaseId</varname> is expected from the client.
- </para>
- </example>
- <example id="zend.xmlrpc.server.use.attach-class-with-arguments-constructor">
- <title>Passing arguments only to constructor</title>
- <para>
- <classname>Zend_XmlRpc_Server</classname> allows to restrict argument passing to
- constructors only. This can be used for constructor dependency injection.
- To limit injection to constructors, call <methodname>sendArgumentsToAllMethods</methodname>
- and pass <code>false</code> as an argument. This disables the default behavior of all arguments
- being injected into the remote method. In the example below the instance of
- <classname>ProductRepository</classname> and <classname>PurchaseRepository</classname> is only
- injected into the constructor of <classname>Services_PricingService2</classname>.
- </para>
- <programlisting language="php"><![CDATA[
- class Services_PricingService2
- {
- /**
- * @param ProductRepository $productRepository
- * @param PurchaseRepository $purchaseRepository
- */
- public function __construct(ProductRepository $productRepository,
- PurchaseRepository $purchaseRepository)
- {
- ...
- }
- /**
- * Calculate current price of product with $productId
- *
- * @param integer $productId
- * @return double
- */
- public function calculate($productId)
- {
- ...
- }
- }
- $server = new Zend_XmlRpc_Server();
- $server->sendArgumentsToAllMethods(false);
- $server->setClass('Services_PricingService2',
- 'pricing',
- new ProductRepository(),
- new PurchaseRepository());
- ]]></programlisting>
- </example>
- <example id="zend.xmlrpc.server.use.attach-instance">
- <title>Attaching a class instance</title>
- <para>
- <methodname>setClass()</methodname> allows to register a previously instantiated
- object at the server. Just pass an instance instead of the class name. Obviously
- passing arguments to the constructor is not possible with pre-instantiated
- objects.
- </para>
- </example>
- <example id="zend.xmlrpc.server.use.attach-several-classes-namespaces">
- <title>Attacher plusieurs classes grâce aux espaces de noms</title>
- <para>
- L'exemple ci dessous montre comment attacher plusieurs classes grâce aux
- espaces de noms.
- </para>
- <programlisting language="php"><![CDATA[
- require_once 'Services/Comb.php';
- require_once 'Services/Brush.php';
- require_once 'Services/Pick.php';
- $server = new Zend_XmlRpc_Server();
- $server->setClass('Services_Comb', 'comb');
- // méthodes appelées sous la forme comb.*
- $server->setClass('Services_Brush', 'brush');
- // méthodes appelées sous la forme brush.*
- $server->setClass('Services_Pick', 'pick');
- // méthodes appelées sous la forme pick.*
- echo $server->handle();
- ]]></programlisting>
- </example>
- <example id="zend.xmlrpc.server.use.exceptions-faults">
- <title>Spécifier les exceptions à utiliser en cas d'erreurs dans les réponses
- XML-RPC</title>
- <para>
- L'exemple ci dessous montre comment spécifier les exceptions à utiliser en cas
- d'erreurs dans les réponses XML-RPC.
- </para>
- <programlisting language="php"><![CDATA[
- require_once 'Services/Exception.php';
- require_once 'Services/Comb.php';
- require_once 'Services/Brush.php';
- require_once 'Services/Pick.php';
- // Utilise les Services_Exception pour les erreurs
- Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');
- $server = new Zend_XmlRpc_Server();
- $server->setClass('Services_Comb', 'comb');
- // méthodes appelées sous la forme comb.*
- $server->setClass('Services_Brush', 'brush');
- // méthodes appelées sous la forme brush.*
- $server->setClass('Services_Pick', 'pick');
- // méthodes appelées sous la forme pick.*
- echo $server->handle();
- ]]></programlisting>
- </example>
- <example id="zend.xmlrpc.server.use.custom-request-object">
- <title>Utiliser un objet de requête personnalisé</title>
- <para>
- Some use cases require to utilize a custom request object.
- For example, <acronym>XML/RPC</acronym> is not bound to
- <acronym>HTTP</acronym> as a transfer protocol. It is possible to use
- other transfer protocols like <acronym>SSH</acronym> or telnet to send
- the request and response data over the wire. Another use case is
- authentication and authorization. In case of a different transfer
- protocol, one need to change the implementation to read request data.
- </para>
- <para>
- L'exemple suivant montre comment utiliser un objet de requête
- personnalisé.
- </para>
- <programlisting language="php"><![CDATA[
- require_once 'Services/Request.php';
- require_once 'Services/Exception.php';
- require_once 'Services/Comb.php';
- require_once 'Services/Brush.php';
- require_once 'Services/Pick.php';
- // Utilise les Services_Exception pour les erreurs
- Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');
- $server = new Zend_XmlRpc_Server();
- $server->setClass('Services_Comb', 'comb');
- // méthodes appelées sous la forme comb.*
- $server->setClass('Services_Brush', 'brush');
- // méthodes appelées sous la forme brush.*
- $server->setClass('Services_Pick', 'pick');
- // méthodes appelées sous la forme pick.*
- // Crée un objet de requête
- $request = new Services_Request();
- echo $server->handle($request);
- ]]></programlisting>
- </example>
- <example id="zend.xmlrpc.server.use.custom-response-object">
- <title>Utiliser un objet de réponse personnalisé</title>
- <para>
- L'exemple suivant montre comment utiliser un objet de réponse
- personnalisé.
- </para>
- <programlisting language="php"><![CDATA[
- require_once 'Services/Request.php';
- require_once 'Services/Response.php';
- require_once 'Services/Exception.php';
- require_once 'Services/Comb.php';
- require_once 'Services/Brush.php';
- require_once 'Services/Pick.php';
- // Utilise les Services_Exception pour les erreurs
- Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');
- $server = new Zend_XmlRpc_Server();
- $server->setClass('Services_Comb', 'comb');
- // méthodes appelées sous la forme comb.*
- $server->setClass('Services_Brush', 'brush');
- // méthodes appelées sous la forme brush.*
- $server->setClass('Services_Pick', 'pick');
- // méthodes appelées sous la forme pick.*
- // Crée un objet de requête
- $request = new Services_Request();
- // Utilise une réponse personnalisée
- $server->setResponseClass('Services_Response');
- echo $server->handle($request);
- ]]></programlisting>
- </example>
- </sect2>
- <sect2 id="zend.xmlrpc.server.performance">
- <title>Optimisation des performances</title>
- <example id="zend.xmlrpc.server.performance.caching">
- <title>Cache entre les requêtes</title>
- <para>
- Les exemples suivants montrent comment gérer une politique de cache
- inter-requêtes.
- </para>
- <programlisting language="php"><![CDATA[
- require_once 'Services/Request.php';
- require_once 'Services/Response.php';
- require_once 'Services/Exception.php';
- require_once 'Services/Comb.php';
- require_once 'Services/Brush.php';
- require_once 'Services/Pick.php';
- // Specifier un fichier de cache
- $cacheFile = dirname(__FILE__) . '/xmlrpc.cache';
- // Utilise les Services_Exception pour les erreurs
- Zend_XmlRpc_Server_Fault::attachFaultException('Services_Exception');
- $server = new Zend_XmlRpc_Server();
- // Essaye de récupérer la définition du serveur via le cache
- if (!Zend_XmlRpc_Server_Cache::get($cacheFile, $server)) {
- $server->setClass('Services_Comb', 'comb');
- // méthodes appelées sous la forme comb.*
- $server->setClass('Services_Brush', 'brush');
- // méthodes appelées sous la forme brush.*
- $server->setClass('Services_Pick', 'pick');
- // méthodes appelées sous la forme pick.*
- // Sauve le cache
- Zend_XmlRpc_Server_Cache::save($cacheFile, $server));
- }
- // Crée un objet de requête
- $request = new Services_Request();
- // Utilise une réponse personnalisée
- $server->setResponseClass('Services_Response');
- echo $server->handle($request);
- ]]></programlisting>
- </example>
- <note>
- <para>
- The server cache file should be located outside the document root.
- </para>
- </note>
- <example id="zend.xmlrpc.server.performance.xmlgen">
- <title>Optimizing XML generation</title>
- <para>
- <classname>Zend_XmlRpc_Server</classname> uses
- <classname>DOMDocument</classname> of <acronym>PHP</acronym>
- extension <emphasis>ext/dom</emphasis> to generate it's
- <acronym>XML</acronym> output. While <emphasis>ext/dom</emphasis> is
- available on a lot of hosts it is is not exactly the fastest.
- Benchmarks have shown, that <classname>XMLWriter</classname>
- from <emphasis>ext/xmlwriter</emphasis> performs better.
- </para>
- <para>
- If <emphasis>ext/xmlwriter</emphasis> is available on your host, you can
- select a the <classname>XMLWriter</classname>-based generator
- to leaverage the performance differences.
- </para>
- <programlisting language="php"><![CDATA[
- require_once 'Zend/XmlRpc/Server.php';
- require_once 'Zend/XmlRpc/Generator/XmlWriter.php';
- Zend_XmlRpc_Value::setGenerator(new Zend_XmlRpc_Generator_XmlWriter());
- $server = new Zend_XmlRpc_Server();
- ...
- ]]></programlisting>
- </example>
- <note>
- <title>Benchmark your application</title>
- <para>
- Performance is determined by a lot of parameters and
- benchmarks only apply for the specific test case. Differences
- come from PHP version, installed extensions, webserver and
- operating system just to name a few. Please make sure to
- benchmark your application on your own and decide which
- generator to use based on <emphasis>your</emphasis> numbers.
- </para>
- </note>
- <note>
- <title>Benchmark your client</title>
- <para>
- This optimization makes sense for the client side too. Just
- select the alternate <acronym>XML</acronym> generator before
- doing any work with <classname>Zend_XmlRpc_Client</classname>.
- </para>
- </note>
- </sect2>
- </sect1>
|