Zend_XmlRpc_Client.xml 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. <sect1 id="zend.xmlrpc.client">
  2. <title>Zend_XmlRpc_Client</title>
  3. <sect2 id="zend.xmlrpc.client.introduction">
  4. <title>Introdución</title>
  5. <para>
  6. Zend Framework provee soporte para consumo remoto para servicios XML-RPC
  7. como un cliente en el paquete <code>Zend_XmlRpc_Client</code>
  8. . Su mejor característica es la conversión automática de tipos
  9. entre PHP y XML-RPC, un servidor de objeto proxy, y acceso a
  10. capacidades de instrospección del servidor.
  11. </para>
  12. </sect2>
  13. <sect2 id="zend.xmlrpc.client.method-calls">
  14. <title>Method Calls</title>
  15. <para>
  16. El constructor de <code>Zend_XmlRpc_Client</code> recibe la
  17. URL del servidor XML-RPC como su primer parámetro.
  18. La nueva instacia devuelta puede ser usada para llamar cualquier número de métodos remotos en el punto final.
  19. </para>
  20. <para>
  21. Para llamar un método remoto con el cliente XML-RPC, instáncealo
  22. y usa el método de instancia <code>call()</code> . El código de ejemplo a continuación utiliza una demostración en el servidor XML-RPC en el sitio web de Zend Framework
  23. . Puede utilizarlo para probar o explorar los componentes
  24. <code>Zend_XmlRpc</code>.
  25. </para>
  26. <example id="zend.xmlrpc.client.method-calls.example-1">
  27. <title>XML-RPC Method Call</title>
  28. <programlisting role="php"><![CDATA[
  29. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  30. echo $client->call('test.sayHello');
  31. // hello
  32. ]]>
  33. </programlisting>
  34. </example>
  35. <para>
  36. El valor XML-RPC devuelto desde la llamada al método remoto automáticamente será convertida al tipo nativo PHP equivalente
  37. . En el ejemplo anterior, es devuelto un <code>string</code> PHP
  38. y está listo para ser usado inmediatamente.
  39. </para>
  40. <para>
  41. El primer parámetro del método <code>call()</code> recibe el nombre del método remoto que llamar. Si el método remoto requiere algún parámetro, éste puede ser enviado por el suministro de un segundo, parámetro opcional a <code>call()</code> con un <code>array</code> de
  42. valores para pasar el método remoto:
  43. </para>
  44. <example id="zend.xmlrpc.client.method-calls.example-2">
  45. <title>XML-RPC Method Call with Parameters</title>
  46. <programlisting role="php"><![CDATA[
  47. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  48. $arg1 = 1.1;
  49. $arg2 = 'foo';
  50. $result = $client->call('test.sayHello', array($arg1, $arg2));
  51. // $result es un tipo nativo PHP
  52. ]]>
  53. </programlisting>
  54. </example>
  55. <para>
  56. si el método remoto no requiere parámetros, este parámetro opcional
  57. podrá ser excluido o se puede pasar un <code>array()</code>
  58. vacío. El array de parámeters para el método repoto puede contener tipos nativos PHPs, objetos <code>Zend_XmlRpc_Value</code>
  59. , o una combinación de estos.
  60. </para>
  61. <para>
  62. El método <code>call()</code> convertirá automáticamente la respuesta
  63. XML-RPC y devolverá su tipo nativo PHP equivalente. Un objeto
  64. <code>Zend_XmlRpc_Response</code> para el valor devuelto también estará
  65. disponible para llamar el método <code>getLastResponse()</code>
  66. después de la llamada.
  67. </para>
  68. </sect2>
  69. <sect2 id="zend.xmlrpc.value.parameters">
  70. <title>Tipos y Conversiones</title>
  71. <para>
  72. Algunas llamadas a métodos remoto requieren parámetros. Éstos son
  73. dados al método <code>call()</code> de <code>Zend_XmlRpc_Client</code>
  74. como un array en el segundo parámetro. Cada parámetro puede ser dado
  75. como un tipo nativo PHP, que será convertido automáticamente,
  76. o como un objeto que representa un tipo específico de XML-RPC
  77. (uno de los objetos <code>Zend_XmlRpc_Value</code>).
  78. </para>
  79. <sect3 id="zend.xmlrpc.value.parameters.php-native">
  80. <title>Tipos Nativos PHP como Parámetro</title>
  81. <para>
  82. Los parámetros pueden ser pasados a <code>call()</code> como variables
  83. PHP nativas, ya sea un <code>string</code>,
  84. <code>integer</code>, <code>float</code>,
  85. <code>boolean</code>, <code>array</code>, o un
  86. <code>object</code>. En este caso, cada tipo PHP nativo será
  87. autodetectado y convertido en uno de los tipos XML-RPC
  88. de acuerdo con esta tabla:
  89. </para>
  90. <table id="zend.xmlrpc.value.parameters.php-native.table-1">
  91. <title>Tipos de Conversión entre PHP y XML-RPC</title>
  92. <tgroup cols="2">
  93. <thead>
  94. <row>
  95. <entry>Tipo Nativo PHP</entry>
  96. <entry>Tipo XML-RPC</entry>
  97. </row>
  98. </thead>
  99. <tbody>
  100. <row>
  101. <entry>integer</entry>
  102. <entry>int</entry>
  103. </row>
  104. <row>
  105. <entry>double</entry>
  106. <entry>double</entry>
  107. </row>
  108. <row>
  109. <entry>boolean</entry>
  110. <entry>boolean</entry>
  111. </row>
  112. <row>
  113. <entry>string</entry>
  114. <entry>string</entry>
  115. </row>
  116. <row>
  117. <entry>array</entry>
  118. <entry>array</entry>
  119. </row>
  120. <row>
  121. <entry>array asociativo</entry>
  122. <entry>struct</entry>
  123. </row>
  124. <row>
  125. <entry>object</entry>
  126. <entry>array</entry>
  127. </row>
  128. </tbody>
  129. </tgroup>
  130. </table>
  131. <note>
  132. <title>¿A qué tipo se convierten los arrays Vacios?</title>
  133. <para>
  134. Pasar un array vacío a un método XML-RPC es problemático,
  135. as it could represent either an array or a struct.
  136. <code>Zend_XmlRpc_Client</code> detects such conditions and
  137. makes a request to the server's
  138. <code>system.methodSignature</code> method to determine the
  139. appropriate XML-RPC type to cast to.
  140. </para>
  141. <para>
  142. However, this in itself can lead to issues. First off,
  143. servers that do not support
  144. <code>system.methodSignature</code> will log failed
  145. requests, and <code>Zend_XmlRpc_Client</code> will resort to
  146. casting the value to an XML-RPC array type. Additionally,
  147. this means that any call with array arguments will result in
  148. an additional call to the remote server.
  149. </para>
  150. <para>
  151. To disable the lookup entirely, you can call the
  152. <code>setSkipSystemLookup()</code> method prior to making
  153. your XML-RPC call:
  154. </para>
  155. <programlisting role="php"><![CDATA[
  156. $client->setSkipSystemLookup(true);
  157. $result = $client->call('foo.bar', array(array()));
  158. ]]>
  159. </programlisting>
  160. </note>
  161. </sect3>
  162. <sect3 id="zend.xmlrpc.value.parameters.xmlrpc-value">
  163. <title><code>Zend_XmlRpc_Value</code> Objects as Parameters</title>
  164. <para>
  165. Parameters may also be created as <code>Zend_XmlRpc_Value</code>
  166. instances to specify an exact XML-RPC type. The primary reasons
  167. for doing this are:
  168. <itemizedlist>
  169. <listitem>
  170. <para>
  171. When you want to make sure the correct parameter
  172. type is passed to the procedure (i.e. the
  173. procedure requires an integer and you may get it
  174. from a database as a string)
  175. </para>
  176. </listitem>
  177. <listitem>
  178. <para>
  179. When the procedure requires <code>base64</code> or
  180. <code>dateTime.iso8601</code> type (which doesn't exists as a
  181. PHP native type)
  182. </para>
  183. </listitem>
  184. <listitem>
  185. <para>
  186. When auto-conversion may fail (i.e. you want to
  187. pass an empty XML-RPC struct as a parameter. Empty
  188. structs are represented as empty arrays in PHP
  189. but, if you give an empty array as a parameter it
  190. will be auto-converted to an XML-RPC array since
  191. it's not an associative array)
  192. </para>
  193. </listitem>
  194. </itemizedlist>
  195. </para>
  196. <para>
  197. There are two ways to create a <code>Zend_XmlRpc_Value</code>
  198. object: instantiate one of the <code>Zend_XmlRpc_Value</code>
  199. subclasses directly, or use the static factory method
  200. <code>Zend_XmlRpc_Value::getXmlRpcValue()</code>.
  201. </para>
  202. <table id="zend.xmlrpc.value.parameters.xmlrpc-value.table-1">
  203. <title><code>Zend_XmlRpc_Value</code> Objects for XML-RPC Types</title>
  204. <tgroup cols="3">
  205. <thead>
  206. <row>
  207. <entry>XML-RPC Type</entry>
  208. <entry><code>Zend_XmlRpc_Value</code> Constant</entry>
  209. <entry><code>Zend_XmlRpc_Value</code> Object</entry>
  210. </row>
  211. </thead>
  212. <tbody>
  213. <row>
  214. <entry>int</entry>
  215. <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER</code></entry>
  216. <entry><code>Zend_XmlRpc_Value_Integer</code></entry>
  217. </row>
  218. <row>
  219. <entry>double</entry>
  220. <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE</code></entry>
  221. <entry><code>Zend_XmlRpc_Value_Double</code></entry>
  222. </row>
  223. <row>
  224. <entry>boolean</entry>
  225. <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN</code></entry>
  226. <entry><code>Zend_XmlRpc_Value_Boolean</code></entry>
  227. </row>
  228. <row>
  229. <entry>string</entry>
  230. <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_STRING</code></entry>
  231. <entry><code>Zend_XmlRpc_Value_String</code></entry>
  232. </row>
  233. <row>
  234. <entry>base64</entry>
  235. <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64</code></entry>
  236. <entry><code>Zend_XmlRpc_Value_Base64</code></entry>
  237. </row>
  238. <row>
  239. <entry>dateTime.iso8601</entry>
  240. <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME</code></entry>
  241. <entry><code>Zend_XmlRpc_Value_DateTime</code></entry>
  242. </row>
  243. <row>
  244. <entry>array</entry>
  245. <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY</code></entry>
  246. <entry><code>Zend_XmlRpc_Value_Array</code></entry>
  247. </row>
  248. <row>
  249. <entry>struct</entry>
  250. <entry><code>Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT</code></entry>
  251. <entry><code>Zend_XmlRpc_Value_Struct</code></entry>
  252. </row>
  253. </tbody>
  254. </tgroup>
  255. </table>
  256. <para>
  257. <note>
  258. <title>Automatic Conversion</title>
  259. <para>
  260. When building a new <code>Zend_XmlRpc_Value</code>
  261. object, its value is set by a PHP type. The PHP type
  262. will be converted to the specified type using
  263. PHP casting. For example, if a string is given as a
  264. value to the <code>Zend_XmlRpc_Value_Integer</code>
  265. object, it will be converted using
  266. <code>(int)$value</code>.
  267. </para>
  268. </note>
  269. </para>
  270. </sect3>
  271. </sect2>
  272. <sect2 id="zend.xmlrpc.client.requests-and-responses">
  273. <title>Server Proxy Object</title>
  274. <para>
  275. Another way to call remote methods with the XML-RPC client is to
  276. use the server proxy. This is a PHP object that proxies a remote
  277. XML-RPC namespace, making it work as close to a native PHP object
  278. as possible.
  279. </para>
  280. <para>
  281. To instantiate a server proxy, call the <code>getProxy()</code>
  282. instance method of <code>Zend_XmlRpc_Client</code>. This will
  283. return an instance of <code>Zend_XmlRpc_Client_ServerProxy</code>.
  284. Any method call on the server proxy object will be forwarded to
  285. the remote, and parameters may be passed like any other PHP
  286. method.
  287. </para>
  288. <example id="zend.xmlrpc.client.requests-and-responses.example-1">
  289. <title>Proxy the Default Namespace</title>
  290. <programlisting role="php"><![CDATA[
  291. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  292. $server = $client->getProxy(); // Proxy the default namespace
  293. $hello = $server->test->sayHello(1, 2); // test.Hello(1, 2) returns "hello"
  294. ]]>
  295. </programlisting>
  296. </example>
  297. <para>
  298. The <code>getProxy()</code> method receives an optional argument
  299. specifying which namespace of the remote server to proxy. If it
  300. does not receive a namespace, the default namespace will be
  301. proxied. In the next example, the <code>test</code> namespace
  302. will be proxied:
  303. </para>
  304. <example id="zend.xmlrpc.client.requests-and-responses.example-2">
  305. <title>Proxy Any Namespace</title>
  306. <programlisting role="php"><![CDATA[
  307. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  308. $test = $client->getProxy('test'); // Proxy the "test" namespace
  309. $hello = $test->sayHello(1, 2); // test.Hello(1,2) returns "hello"
  310. ]]>
  311. </programlisting>
  312. </example>
  313. <para>
  314. If the remote server supports nested namespaces of any depth,
  315. these can also be used through the server proxy. For example, if
  316. the server in the example above had a method
  317. <code>test.foo.bar()</code>, it could be called as
  318. <code>$test-&gt;foo-&gt;bar()</code>.
  319. </para>
  320. </sect2>
  321. <sect2 id="zend.xmlrpc.client.error-handling">
  322. <title>Error Handling</title>
  323. <para>
  324. Two kinds of errors can occur during an XML-RPC method call: HTTP
  325. errors and XML-RPC faults. The <code>Zend_XmlRpc_Client</code>
  326. recognizes each and provides the ability to detect and trap them
  327. independently.
  328. </para>
  329. <sect3 id="zend.xmlrpc.client.error-handling.http">
  330. <title>HTTP Errors</title>
  331. <para>
  332. If any HTTP error occurs, such as the remote HTTP server
  333. returns a <code>404 Not Found</code>, a
  334. <code>Zend_XmlRpc_Client_HttpException</code> will be thrown.
  335. </para>
  336. <example id="zend.xmlrpc.client.error-handling.http.example-1">
  337. <title>Handling HTTP Errors</title>
  338. <programlisting role="php"><![CDATA[
  339. $client = new Zend_XmlRpc_Client('http://foo/404');
  340. try {
  341. $client->call('bar', array($arg1, $arg2));
  342. } catch (Zend_XmlRpc_Client_HttpException $e) {
  343. // $e->getCode() returns 404
  344. // $e->getMessage() returns "Not Found"
  345. }
  346. ]]>
  347. </programlisting>
  348. </example>
  349. <para>
  350. Regardless of how the XML-RPC client is used, the
  351. <code>Zend_XmlRpc_Client_HttpException</code> will be thrown
  352. whenever an HTTP error occurs.
  353. </para>
  354. </sect3>
  355. <sect3 id="zend.xmlrpc.client.error-handling.faults">
  356. <title>XML-RPC Faults</title>
  357. <para>
  358. An XML-RPC fault is analogous to a PHP exception. It is a
  359. special type returned from an XML-RPC method call that has
  360. both an error code and an error message. XML-RPC faults are
  361. handled differently depending on the context of how the
  362. <code>Zend_XmlRpc_Client</code> is used.
  363. </para>
  364. <para>
  365. When the <code>call()</code> method or the server
  366. proxy object is used, an XML-RPC fault will result in a
  367. <code>Zend_XmlRpc_Client_FaultException</code> being thrown.
  368. The code and message of the exception will map directly to
  369. their respective values in the original XML-RPC fault
  370. response.
  371. </para>
  372. <example id="zend.xmlrpc.client.error-handling.faults.example-1">
  373. <title>Handling XML-RPC Faults</title>
  374. <programlisting role="php"><![CDATA[
  375. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  376. try {
  377. $client->call('badMethod');
  378. } catch (Zend_XmlRpc_Client_FaultException $e) {
  379. // $e->getCode() returns 1
  380. // $e->getMessage() returns "Unknown method"
  381. }
  382. ]]>
  383. </programlisting>
  384. </example>
  385. <para>
  386. Cuando el método <code>call()</code> es usado para realizar la
  387. petición, <code>Zend_XmlRpc_Client_FaultException</code> será
  388. lanzado como error. Un objeto <code>Zend_XmlRpc_Response</code> conteniendo
  389. el error estará disponible llamando a
  390. <code>getLastResponse()</code>.
  391. </para>
  392. <para>
  393. Cuando el método <code>doRequest()</code> sea usado para realizar una
  394. petición, no lanzará una excepción. En vez de eso, devolverá un objeto
  395. <code>Zend_XmlRpc_Response</code> que contendrá el error.
  396. Esto puede comprobarse con
  397. <code>isFault()</code> método instancia de
  398. <code>Zend_XmlRpc_Response</code>.
  399. </para>
  400. </sect3>
  401. </sect2>
  402. <sect2 id="zend.xmlrpc.client.introspection">
  403. <title>Server Introspection</title>
  404. <para>
  405. Some XML-RPC servers support the de facto introspection methods under the XML-RPC
  406. <code>system.</code> namespace. <code>Zend_XmlRpc_Client</code> provides special
  407. support for servers with these capabilities.
  408. </para>
  409. <para>
  410. A <code>Zend_XmlRpc_Client_ServerIntrospection</code> instance may be retrieved by calling
  411. the <code>getIntrospector()</code> method of <code>Zend_XmlRpcClient</code>. It can
  412. then be used to perform introspection operations on the server.
  413. </para>
  414. </sect2>
  415. <sect2 id="zend.xmlrpc.client.request-to-response">
  416. <title>From Request to Response</title>
  417. <para>
  418. Under the hood, the <code>call()</code> instance method of <code>Zend_XmlRpc_Client</code>
  419. builds a request object (<code>Zend_XmlRpc_Request</code>) and sends it to another method,
  420. <code>doRequest()</code>, that returns a response object (<code>Zend_XmlRpc_Response</code>).
  421. </para>
  422. <para>
  423. The <code>doRequest()</code> method is also available for use directly:
  424. </para>
  425. <example id="zend.xmlrpc.client.request-to-response.example-1">
  426. <title>Processing Request to Response</title>
  427. <programlisting role="php"><![CDATA[
  428. $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
  429. $request = new Zend_XmlRpc_Request();
  430. $request->setMethod('test.sayHello');
  431. $request->setParams(array('foo', 'bar'));
  432. $client->doRequest($request);
  433. // $server->getLastRequest() returns instanceof Zend_XmlRpc_Request
  434. // $server->getLastResponse() returns instanceof Zend_XmlRpc_Response
  435. ]]>
  436. </programlisting>
  437. </example>
  438. <para>
  439. Whenever an XML-RPC method call is made by the client through any
  440. means, either the <code>call()</code> method,
  441. <code>doRequest()</code> method, or server proxy, the last request
  442. object and its resultant response object will always be available
  443. through the methods <code>getLastRequest()</code> and
  444. <code>getLastResponse()</code> respectively.
  445. </para>
  446. </sect2>
  447. <sect2 id="zend.xmlrpc.client.http-client">
  448. <title>HTTP Client and Testing</title>
  449. <para>
  450. In all of the prior examples, an HTTP client was never specified.
  451. When this is the case, a new instance of
  452. <code>Zend_Http_Client</code> will be created with its default
  453. options and used by <code>Zend_XmlRpc_Client</code> automatically.
  454. </para>
  455. <para>
  456. The HTTP client can be retrieved at any time with the
  457. <code>getHttpClient()</code> method. For most cases, the default
  458. HTTP client will be sufficient. However, the
  459. <code>setHttpClient()</code> method allows for a different HTTP
  460. client instance to be injected.
  461. </para>
  462. <para>
  463. The <code>setHttpClient()</code> is particularly useful for unit testing. When combined
  464. with the <code>Zend_Http_Client_Adapter_Test</code>, remote services can be mocked
  465. out for testing. See the unit tests for <code>Zend_XmlRpc_Client</code> for examples
  466. of how to do this.
  467. </para>
  468. </sect2>
  469. </sect1>
  470. <!--
  471. vim:se ts=4 sw=4 et:
  472. -->