Zend_XmlRpc_Client.xml 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. <!-- EN-Revision: 13825 -->
  2. <sect1 id="zend.xmlrpc.client">
  3. <title>Zend_XmlRpc_Client</title>
  4. <sect2 id="zend.xmlrpc.client.introduction">
  5. <title>Introduction</title>
  6. <para>Zend Framework possède la capacité de consommer des services distants XML-RPC, via la classe
  7. <classname>Zend_XmlRpc_Client</classname>. Ses caractéristiques principales sont la conversion automatique des types entre
  8. PHP et XML-RPC, un objet proxy de serveur, et des possibilités d'introspection du serveur.</para>
  9. </sect2>
  10. <sect2 id="zend.xmlrpc.client.method-calls">
  11. <title>Appels de méthodes</title>
  12. <para>Le constructeur de <classname>Zend_XmlRpc_Client</classname> reçoit en premier paramètre l'URL du serveur XML-RPC
  13. distant. L'instance retournée pourra alors être utilisée pour appeler n'importe quelle méthode distante.</para>
  14. <para>Pour appeler une méthode distante, utilisez la méthode <code>call()</code> de votre instance. Le code
  15. suivant montre un exemple avec le serveur XML-RPC du site de Zend Framework. Vous pouvez l'utiliser pour tester
  16. ou explorer les possibilités des composants <classname>Zend_XmlRpc</classname>.</para>
  17. <example id="zend.xmlrpc.client.method-calls.example-1">
  18. <title>XML-RPC appel de méthode</title>
  19. <programlisting role="php"><![CDATA[
  20. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  21. echo $client->call('test.sayHello');
  22. // hello
  23. ]]></programlisting>
  24. </example>
  25. <para>Le type de la valeur XML-RPC retournée sera automatiquement casté en un type compatible PHP. Dans
  26. l'exemple ci-dessus, une <code>string</code> PHP est retournée et immédiatement utilisable.</para>
  27. <para>Le premier paramètre de <code>call()</code> est le nom de la méthode distante à appeler. Si celle-ci
  28. demande des paramètres, ceux-ci doivent alors être passés via le deuxième paramètre de <code>call()</code>, sous
  29. forme de tableau PHP (<code>array</code>) :</para>
  30. <example id="zend.xmlrpc.client.method-calls.example-2">
  31. <title>XML-RPC appel de méthode avec des paramètres</title>
  32. <programlisting role="php"><![CDATA[
  33. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  34. $arg1 = 1.1;
  35. $arg2 = 'foo';
  36. $result = $client->call('test.sayHello', array($arg1, $arg2));
  37. // $result est un type PHP natif
  38. ]]></programlisting>
  39. </example>
  40. <para>Le tableau de paramètres peut contenir des types PHP natifs, des objets <classname>Zend_XmlRpc_Value</classname>, ou
  41. bien les deux à la fois.</para>
  42. <para>La méthode <code>call()</code> convertira automatiquement la réponse XML-RPC et retournera un type PHP
  43. natif valide. Un objet <classname>Zend_XmlRpc_Response</classname> pour la valeur de retour sera de même disponible, via
  44. un appel à <code>getLastResponse()</code>.</para>
  45. </sect2>
  46. <sect2 id="zend.xmlrpc.value.parameters">
  47. <title>Types et conversions</title>
  48. <para>Certaines méthodes distantes requièrent des paramètres. Ceux-ci sont donnés sous forme de tableau PHP à
  49. <code>call()</code>. Chaque paramètre est supposé être un type PHP natif qui sera alors lui-même converti, ou
  50. alors un objet représentant un type XML-RPC (un objet parmi les <classname>Zend_XmlRpc_Value</classname>).</para>
  51. <sect3 id="zend.xmlrpc.value.parameters.php-native">
  52. <title>Types PHP natifs comme paramètres</title>
  53. <para>Les paramètres passés à <code>call()</code> peuvent être d'un type PHP natif, à savoir
  54. <code>string</code>, <code>integer</code>, <code>float</code>, <code>boolean</code>, <code>array</code>, ou
  55. <code>object</code>. Dans ce cas, chacun des types sera converti de manière automatique en son type
  56. compatible XML-RPC, suivant la table suivante :</para>
  57. <table id="zend.xmlrpc.value.parameters.php-native.table-1">
  58. <title>PHP et XML-RPC, conversions de types</title>
  59. <tgroup cols="2">
  60. <thead>
  61. <row>
  62. <entry>Type PHP natif</entry>
  63. <entry>XML-RPC type</entry>
  64. </row>
  65. </thead>
  66. <tbody>
  67. <row>
  68. <entry>integer</entry>
  69. <entry>int</entry>
  70. </row>
  71. <row>
  72. <entry>double</entry>
  73. <entry>double</entry>
  74. </row>
  75. <row>
  76. <entry>boolean</entry>
  77. <entry>boolean</entry>
  78. </row>
  79. <row>
  80. <entry>string</entry>
  81. <entry>string</entry>
  82. </row>
  83. <row>
  84. <entry>array</entry>
  85. <entry>array</entry>
  86. </row>
  87. <row>
  88. <entry>associative array</entry>
  89. <entry>struct</entry>
  90. </row>
  91. <row>
  92. <entry>object</entry>
  93. <entry>array</entry>
  94. </row>
  95. </tbody>
  96. </tgroup>
  97. </table>
  98. <note>
  99. <title>Comment est casté un tableau vide ?</title>
  100. <para>Fournir un tableau vide à une méthode XML-RPC est problématique, car il peut être représenté sous
  101. la forme soit d'un tableau, soit d'une structure ("struct"). <classname>Zend_XmlRpc_Client</classname> détecte ce
  102. genre de conditions et fait une requête vers la méthode <code>system.methodSignature</code> du serveur
  103. pour déterminer le type XML-RPC approprié vers le quel casté.</para>
  104. <para>Cependant, ceci peut mener malgré tout à des soucis. Premièrement, les serveurs qui ne supportent
  105. <code>system.methodSignature</code> vont retourner une requête de type échec, et
  106. <classname>Zend_XmlRpc_Client</classname> résultera en un cast de la valeur de type tableau XML-RPC ("array"). De
  107. plus, ceci sous-entend que tout appel avec des arguments de type tableau entraîneront un appel
  108. additionnel au serveur distant.</para>
  109. <para>Pour désactiver entièrement la recherche, vous pouvez appeler la méthode
  110. <code>setSkipSystemLookup()</code> avant de réaliser votre appel XML-RPC :</para>
  111. <programlisting role="php"><![CDATA[
  112. $client->setSkipSystemLookup(true);
  113. $result = $client->call('foo.bar', array(array()));
  114. ]]></programlisting>
  115. </note>
  116. </sect3>
  117. <sect3 id="zend.xmlrpc.value.parameters.xmlrpc-value">
  118. <title>Objets <classname>Zend_XmlRpc_Value</classname> en tant que paramètres</title>
  119. <para>Les paramètres peuvent aussi être des objets <classname>Zend_XmlRpc_Value</classname> qui spécifient alors
  120. exactement un type XML-RPC. Les raisons principales d'utiliser un tel procédé sont : <itemizedlist>
  121. <listitem>
  122. <para>Lorsque vous voulez être certain du type de paramètre (la méthode attend un entier et vous
  123. le récupérez sous forme de chaîne de caractères depuis une base de données).</para>
  124. </listitem>
  125. <listitem>
  126. <para>Lorsque la méthode attend un type <code>base64</code> ou <code>dateTime.iso8601</code>
  127. (ceux-ci n'existant pas nativement dans le langage PHP).</para>
  128. </listitem>
  129. <listitem>
  130. <para>Lorsque la conversion de types (cast) peut échouer (vous voulez passer une valeur XML-RPC
  131. vide comme paramètre. Mais les valeurs vides en PHP sont représentés sous forme de tableaux
  132. vides, or si vous passez un tableau vide à votre méthode <code>call</code>, il va être converti
  133. en un tableau XML-RPC, comme ce n'est pas un tableau associatif).</para>
  134. </listitem>
  135. </itemizedlist></para>
  136. <para>Deux manières existent pour créer des objets <classname>Zend_XmlRpc_Value</classname> : instanciez une
  137. sous-classe <classname>Zend_XmlRpc_Value</classname> directement, ou utilisez une fabrique ("factory method") telle
  138. que <classname>Zend_XmlRpc_Value::getXmlRpcValue()</classname>.</para>
  139. <table id="zend.xmlrpc.value.parameters.xmlrpc-value.table-1">
  140. <title>Objets <classname>Zend_XmlRpc_Value</classname> comme types XML-RPC</title>
  141. <tgroup cols="3">
  142. <thead>
  143. <row>
  144. <entry>XML-RPC Type</entry>
  145. <entry><classname>Zend_XmlRpc_Value</classname> Constante</entry>
  146. <entry><classname>Zend_XmlRpc_Value</classname> Objet</entry>
  147. </row>
  148. </thead>
  149. <tbody>
  150. <row>
  151. <entry>int</entry>
  152. <entry><classname>Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER</classname></entry>
  153. <entry><classname>Zend_XmlRpc_Value_Integer</classname></entry>
  154. </row>
  155. <row>
  156. <entry>double</entry>
  157. <entry><classname>Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE</classname></entry>
  158. <entry><classname>Zend_XmlRpc_Value_Double</classname></entry>
  159. </row>
  160. <row>
  161. <entry>boolean</entry>
  162. <entry><classname>Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN</classname></entry>
  163. <entry><classname>Zend_XmlRpc_Value_Boolean</classname></entry>
  164. </row>
  165. <row>
  166. <entry>string</entry>
  167. <entry><classname>Zend_XmlRpc_Value::XMLRPC_TYPE_STRING</classname></entry>
  168. <entry><classname>Zend_XmlRpc_Value_String</classname></entry>
  169. </row>
  170. <row>
  171. <entry>base64</entry>
  172. <entry><classname>Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64</classname></entry>
  173. <entry><classname>Zend_XmlRpc_Value_Base64</classname></entry>
  174. </row>
  175. <row>
  176. <entry>dateTime.iso8601</entry>
  177. <entry><classname>Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME</classname></entry>
  178. <entry><classname>Zend_XmlRpc_Value_DateTime</classname></entry>
  179. </row>
  180. <row>
  181. <entry>array</entry>
  182. <entry><classname>Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY</classname></entry>
  183. <entry><classname>Zend_XmlRpc_Value_Array</classname></entry>
  184. </row>
  185. <row>
  186. <entry>struct</entry>
  187. <entry><classname>Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT</classname></entry>
  188. <entry><classname>Zend_XmlRpc_Value_Struct</classname></entry>
  189. </row>
  190. </tbody>
  191. </tgroup>
  192. </table>
  193. <para><note>
  194. <title>Conversion automatique</title>
  195. <para>Lorsque vous créez un objet <classname>Zend_XmlRpc_Value</classname>, sa valeur est déterminée par un
  196. type PHP. Celui-ci va être converti vers le type désiré en utilisant le cast PHP. Par exemple si une
  197. chaîne de caractères est donnée comme valeur à un objet <classname>Zend_XmlRpc_Value_Integer</classname>, elle
  198. sera alors convertie suivant la règle <code>(int)$value</code>.</para>
  199. </note></para>
  200. </sect3>
  201. </sect2>
  202. <sect2 id="zend.xmlrpc.client.requests-and-responses">
  203. <title>Objet proxy du serveur</title>
  204. <para>Un autre moyen d'appeler des méthodes avec un client XML-RPC est d'utiliser le proxy du serveur. C'est un
  205. objet PHP qui proxie un espace de nom XML-RPC, en fonctionnant autant que possible comme les objets PHP.</para>
  206. <para>Pour instancier un proxy serveur, appelez <code>getProxy()</code> de <classname>Zend_XmlRpc_Client</classname>. Elle
  207. retourne un objet <classname>Zend_XmlRpc_Client_ServerProxy</classname>. Tout appel de méthode sur l'objet proxy sera
  208. proxié vers le serveur XML-RPC, et les paramètres seront utilisés comme pour une méthode PHP banale.</para>
  209. <example id="zend.xmlrpc.client.requests-and-responses.example-1">
  210. <title>Proxy espace de nom par défaut</title>
  211. <programlisting role="php"><![CDATA[
  212. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  213. $server = $client->getProxy();
  214. // Proxy l'espace de nom par défaut
  215. $hello = $server->test->sayHello(1, 2);
  216. // test.Hello(1, 2) retourne "hello"
  217. ]]></programlisting>
  218. </example>
  219. <para>La méthode <code>getProxy()</code> reçoit un argument optionnel désignant l'espace de nom à utiliser par
  220. le proxy. Par défaut, il s'agit de l'espace général, voici un exemple utilisant un espace de nom
  221. <code>test</code> :</para>
  222. <example id="zend.xmlrpc.client.requests-and-responses.example-2">
  223. <title>Proxy un espace de nom</title>
  224. <programlisting role="php"><![CDATA[
  225. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  226. $test = $client->getProxy('test');
  227. // Proxy l'espace de nommage "test"
  228. $hello = $test->sayHello(1, 2);
  229. // test.Hello(1,2) retourne "hello"
  230. ]]></programlisting>
  231. </example>
  232. <para>Si le serveur distant supporte les espaces de noms imbriqués, alors le proxy les supportera. Par exemple,
  233. si le serveur dans l'exemple ci-dessus acceptait les espaces de noms imbriqués, alors sa méthode
  234. <code>test.foo.bar()</code> aurait pu être appelée via <code>$test-&gt;foo-&gt;bar()</code>.</para>
  235. </sect2>
  236. <sect2 id="zend.xmlrpc.client.error-handling">
  237. <title>Gestion des erreurs</title>
  238. <para>Deux types d'erreurs peuvent être distingués : erreurs HTTP, ou erreurs XML-RPC. L'objet
  239. <classname>Zend_XmlRpc_Client</classname> reconnaît ces erreurs et fournit les moyens de les repérer et de les
  240. gérer.</para>
  241. <sect3 id="zend.xmlrpc.client.error-handling.http">
  242. <title>Erreurs HTTP</title>
  243. <para>Si une erreur HTTP survient, par exemple le serveur renvoie un <code>404 Not Found</code>, alors une
  244. <classname>Zend_XmlRpc_Client_HttpException</classname> sera levée.</para>
  245. <example id="zend.xmlrpc.client.error-handling.http.example-1">
  246. <title>Gérer les erreurs HTTP</title>
  247. <programlisting role="php"><![CDATA[
  248. $client = new Zend_XmlRpc_Client('http://foo/404');
  249. try {
  250. $client->call('bar', array($arg1, $arg2));
  251. } catch (Zend_XmlRpc_Client_HttpException $e) {
  252. // $e->getCode() retourne 404
  253. // $e->getMessage() retourne "Not Found"
  254. }
  255. ]]></programlisting>
  256. </example>
  257. <para>Quelque soit l'utilisation du client XML-RPC, une <classname>Zend_XmlRpc_Client_HttpException</classname> sera
  258. systématiquement levée lorsqu'une erreur HTTP de quelque type que ce soit est rencontrée.</para>
  259. </sect3>
  260. <sect3 id="zend.xmlrpc.client.error-handling.faults">
  261. <title>Erreurs XML-RPC (Faults)</title>
  262. <para>Une erreur XML-RPC peut être assimilée à une exception en PHP. C'est un type spécial retourné par une
  263. des méthodes du client XML-RPC, et ce type contient un message, et un code d'erreur. Les erreurs XML-RPC
  264. seront gérées différemment en fonction du contexte d'utilisation de l'objet
  265. <classname>Zend_XmlRpc_Client</classname>.</para>
  266. <para>Lors de l'utilisation de la méthode <code>call()</code>, ou de l'objet proxy serveur, une erreur
  267. XML-RPC aura pour effet de lancer une <classname>Zend_XmlRpc_Client_FaultException</classname>. Le code et le message
  268. de l'exception seront rendus dans leurs valeurs respectives de la réponse XML-RPC.</para>
  269. <example id="zend.xmlrpc.client.error-handling.faults.example-1">
  270. <title>Gérer les erreurs XML-RPC</title>
  271. <programlisting role="php"><![CDATA[
  272. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  273. try {
  274. $client->call('badMethod');
  275. } catch (Zend_XmlRpc_Client_FaultException $e) {
  276. // $e->getCode() retourne 1
  277. // $e->getMessage() retourne "Unknown method"
  278. }
  279. ]]></programlisting>
  280. </example>
  281. <para>En utilisant <code>call()</code>, une exception <classname>Zend_XmlRpc_Client_FaultException</classname> sera
  282. donc lancée si une erreur survient. Un objet <classname>Zend_XmlRpc_Response</classname> contenant l'erreur sera de
  283. même disponible via la méthode <code>getLastResponse()</code>.</para>
  284. <para>Lors de l'utilisation de la méthode <code>doRequest()</code>, aucune exception ne sera levée si une
  285. erreur XML-RPC survient. Simplement, l'objet <classname>Zend_XmlRpc_Response</classname> retourné contiendra l'erreur.
  286. Vérifiez-en l'état avec <code>isFault()</code>.</para>
  287. </sect3>
  288. </sect2>
  289. <sect2 id="zend.xmlrpc.client.introspection">
  290. <title>Introspection du serveur</title>
  291. <para>Certains serveurs XML-RPC supportent l'introspection de leurs méthodes au travers de l'espace de noms
  292. <code>system.</code> <classname>Zend_XmlRpc_Client</classname> fournit un support d'un tel procédé.</para>
  293. <para>Une instance de <classname>Zend_XmlRpc_Client_ServerIntrospection</classname> sera retournée si vous appelez la
  294. méthode <code>getIntrospector()</code> sur l'objet <classname>Zend_XmlRpcClient</classname>.</para>
  295. </sect2>
  296. <sect2 id="zend.xmlrpc.client.request-to-response">
  297. <title>De la requête à la réponse</title>
  298. <para>Dans les faits, la méthode <code>call()</code> de <classname>Zend_XmlRpc_Client</classname> fabrique un objet
  299. <classname>Zend_XmlRpc_Request</classname> et l'envoie à une méthode <code>doRequest()</code>, qui retourne un objet de
  300. réponse <classname>Zend_XmlRpc_Response</classname>.</para>
  301. <para>La méthode <code>doRequest()</code> est disponible directement si besoin :</para>
  302. <example id="zend.xmlrpc.client.request-to-response.example-1">
  303. <title>Effectuer une requête et récupérer une réponse manuellement</title>
  304. <programlisting role="php"><![CDATA[
  305. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  306. $request = new Zend_XmlRpc_Request();
  307. $request->setMethod('test.sayHello');
  308. $request->setParams(array('foo', 'bar'));
  309. $client->doRequest($request);
  310. // $server->getLastRequest() retoure instanceof Zend_XmlRpc_Request
  311. // $server->getLastResponse() retourne instanceof Zend_XmlRpc_Response
  312. ]]></programlisting>
  313. </example>
  314. <para>Lorsqu'une méthode XML-RPC est appelée, quel qu'en soit le moyen, (<code>call()</code>,
  315. <code>doRequest()</code> ou proxy serveur), le dernier objet de requête, et son homologue de réponse, seront
  316. toujours disponibles, au travers des appels à <code>getLastRequest()</code> et
  317. <code>getLastResponse()</code>.</para>
  318. </sect2>
  319. <sect2 id="zend.xmlrpc.client.http-client">
  320. <title>Client HTTP et tests</title>
  321. <para>Dans tous les exemples utilisés sur cette page, nous ne parlons jamais du client HTTP. Lorsque c'est
  322. nécessaire, une instance de <classname>Zend_Http_Client</classname> sera créée par défaut et injectée dans
  323. <classname>Zend_XmlRpc_Client</classname> de manière automatique.</para>
  324. <para>L'objet client HTTP peut être récupéré à tout moment grâce à la méthode <code>getHttpClient()</code>.
  325. <code>setHttpClient()</code> permet d'injecter un objet <classname>Zend_Http_Client</classname>.</para>
  326. <para><code>setHttpClient()</code> est particulièrement utilisée pour les tests unitaires. Lorsque combinée avec
  327. <classname>Zend_Http_Client_Adapter_Test</classname>, les services Web peuvent être déguisés (émulés) pour les tests.
  328. Voyez les tests unitaires de <classname>Zend_XmlRpc_Client</classname> pour des exemples concrets.</para>
  329. </sect2>
  330. </sect1>