1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 20794 -->
4 <sect1 id="zend.xmlrpc.client">
5 <title>Zend_XmlRpc_Client</title>
7 <sect2 id="zend.xmlrpc.client.introduction">
8 <title>Introdución</title>
11 Zend Framework provee soporte para consumo remoto para servicios
12 <acronym>XML-RPC</acronym>
13 como un cliente en el paquete
14 <classname>Zend_XmlRpc_Client</classname>
16 característica es la conversión automática de tipos entre
17 <acronym>PHP</acronym>
19 <acronym>XML-RPC</acronym>
21 de objeto proxy, y acceso a capacidades de instrospección del
27 <sect2 id="zend.xmlrpc.client.method-calls">
28 <title>Method Calls</title>
32 <classname>Zend_XmlRpc_Client</classname>
34 <acronym>URL</acronym>
36 <acronym>XML-RPC</acronym>
37 como su primer parámetro. La nueva
38 instacia devuelta puede ser usada para llamar
40 métodos remotos en el punto final.
44 Para llamar un método remoto con el cliente
45 <acronym>XML-RPC</acronym>
46 , instáncealo y usa el método de
48 <methodname>call()</methodname>
49 . El código de ejemplo a
50 continuación utiliza una demostración en el servidor
51 <acronym>XML-RPC</acronym>
52 en el sitio web de Zend Framework .
53 Puede utilizarlo para probar o explorar los
55 <classname>Zend_XmlRpc</classname>
59 <example id="zend.xmlrpc.client.method-calls.example-1">
60 <title>XML-RPC Method Call</title>
61 <programlisting language="php"><![CDATA[
62 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
64 echo $client->call('test.sayHello');
72 <acronym>XML-RPC</acronym>
73 devuelto desde la llamada al
74 método remoto automáticamente será convertida al tipo nativo
75 <acronym>PHP</acronym>
76 equivalente . En el ejemplo anterior, es
79 <acronym>PHP</acronym>
80 y está listo para ser usado inmediatamente.
84 El primer parámetro del método
85 <methodname>call()</methodname>
86 recibe el nombre del método remoto que llamar. Si el método remoto
88 parámetro, éste puede ser enviado por el suministro
89 de un segundo, parámetro opcional a
90 <methodname>call()</methodname>
93 de valores para pasar el
97 <example id="zend.xmlrpc.client.method-calls.example-2">
98 <title>XML-RPC Method Call with Parameters</title>
99 <programlisting language="php"><![CDATA[
100 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
105 $result = $client->call('test.sayHello', array($arg1, $arg2));
107 // $result es un tipo nativo PHP
112 si el método remoto no requiere parámetros, este parámetro
113 opcional podrá ser excluido o
115 <methodname>array()</methodname>
116 vacío. El array de parámeters
117 para el método repoto puede contener tipos nativos
118 <acronym>PHP</acronym>
120 <classname>Zend_XmlRpc_Value</classname>
127 <methodname>call()</methodname>
129 automáticamente la respuesta
130 <acronym>XML-RPC</acronym>
133 <acronym>PHP</acronym>
134 equivalente. Un objeto
135 <classname>Zend_XmlRpc_Response</classname>
137 devuelto también estará disponible para llamar el método
138 <methodname>getLastResponse()</methodname>
144 <sect2 id="zend.xmlrpc.value.parameters">
145 <title>Tipos y Conversiones</title>
147 Algunas llamadas a métodos remoto requieren parámetros. Éstos son
149 <methodname>call()</methodname>
151 <classname>Zend_XmlRpc_Client</classname>
153 segundo parámetro. Cada parámetro puede ser dado como un tipo nativo
154 <acronym>PHP</acronym>
155 , que será convertido automáticamente, o
156 como un objeto que representa un tipo específico
158 <acronym>XML-RPC</acronym>
160 <classname>Zend_XmlRpc_Value</classname>
164 <sect3 id="zend.xmlrpc.value.parameters.php-native">
165 <title>Tipos Nativos PHP como Parámetro</title>
167 Los parámetros pueden ser pasados a
168 <methodname>call()</methodname>
170 <acronym>PHP</acronym>
183 . En este caso, cada tipo
184 <acronym>PHP</acronym>
185 nativo será autodetectado y convertido en uno de los tipos
186 <acronym>XML-RPC</acronym>
187 de acuerdo con esta tabla:
190 <table id="zend.xmlrpc.value.parameters.php-native.table-1">
191 <title>Tipos de Conversión entre PHP y
198 <acronym>PHP</acronym>
202 <acronym>XML-RPC</acronym>
208 <entry>integer</entry>
212 <entry>Zend_Crypt_Math_BigInteger</entry>
217 <entry>double</entry>
218 <entry>double</entry>
221 <entry>boolean</entry>
222 <entry>boolean</entry>
225 <entry>string</entry>
226 <entry>string</entry>
238 <entry>array asociativo</entry>
239 <entry>struct</entry>
242 <entry>object</entry>
246 <entry>Zend_Date</entry>
247 <entry>dateTime.iso8601</entry>
250 <entry>DateTime</entry>
251 <entry>dateTime.iso8601</entry>
259 <title>¿A qué tipo se convierten los arrays Vacios?</title>
262 Passing an empty array to an
263 <acronym>XML-RPC</acronym>
264 method is problematic,
265 as it could represent either an array or a struct.
266 <classname>Zend_XmlRpc_Client</classname>
267 detects such conditions and
268 makes a request to the server's
269 <command>system.methodSignature</command>
270 method to determine the
272 <acronym>XML-RPC</acronym>
277 However, this in itself can lead to issues. First off,
280 <command>system.methodSignature</command>
283 <classname>Zend_XmlRpc_Client</classname>
285 casting the value to an
286 <acronym>XML-RPC</acronym>
287 array type. Additionally,
288 this means that any call with array arguments will
290 an additional call to the remote server.
294 To disable the lookup entirely, you can call the
295 <methodname>setSkipSystemLookup()</methodname>
296 method prior to making
298 <acronym>XML-RPC</acronym>
302 <programlisting language="php"><![CDATA[
303 $client->setSkipSystemLookup(true);
304 $result = $client->call('foo.bar', array(array()));
309 <sect3 id="zend.xmlrpc.value.parameters.xmlrpc-value">
310 <title>Zend_XmlRpc_Value Objects as Parameters</title>
312 Parameters may also be created as
313 <classname>Zend_XmlRpc_Value</classname>
314 instances to specify an exact
315 <acronym>XML-RPC</acronym>
316 type. The primary reasons
322 When you want to make sure the correct parameter
323 type is passed to the
325 procedure requires an integer and you may get it
327 a database as a string)
332 When the procedure requires
333 <property>base64</property>
335 <property>dateTime.iso8601</property>
336 type (which doesn't exists as a
337 <acronym>PHP</acronym>
343 When auto-conversion may fail (i.e. you want to
345 <acronym>XML-RPC</acronym>
346 struct as a parameter. Empty
347 structs are represented as empty arrays in
348 <acronym>PHP</acronym>
349 but, if you give an empty array as a parameter it
350 will be auto-converted
352 <acronym>XML-RPC</acronym>
354 it's not an associative array)
361 There are two ways to create a
362 <classname>Zend_XmlRpc_Value</classname>
363 object: instantiate one of the
364 <classname>Zend_XmlRpc_Value</classname>
365 subclasses directly, or use the static factory method
366 <methodname>Zend_XmlRpc_Value::getXmlRpcValue()</methodname>
370 <table id="zend.xmlrpc.value.parameters.xmlrpc-value.table-1">
371 <title>Zend_XmlRpc_Value Objects for XML-RPC Types</title>
376 <acronym>XML-RPC</acronym>
380 <classname>Zend_XmlRpc_Value</classname>
384 <classname>Zend_XmlRpc_Value</classname>
393 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER</constant>
396 <classname>Zend_XmlRpc_Value_Integer</classname>
402 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_I8</constant>
405 <classname>Zend_XmlRpc_Value_BigInteger</classname>
411 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_APACHEI8</constant>
414 <classname>Zend_XmlRpc_Value_BigInteger</classname>
418 <entry>double</entry>
420 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE</constant>
423 <classname>Zend_XmlRpc_Value_Double</classname>
427 <entry>boolean</entry>
429 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN</constant>
432 <classname>Zend_XmlRpc_Value_Boolean</classname>
436 <entry>string</entry>
438 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_STRING</constant>
441 <classname>Zend_XmlRpc_Value_String</classname>
447 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_NIL</constant>
450 <classname>Zend_XmlRpc_Value_Nil</classname>
454 <entry>ex:nil</entry>
456 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_APACHENIL</constant>
459 <classname>Zend_XmlRpc_Value_Nil</classname>
463 <entry>base64</entry>
465 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64</constant>
468 <classname>Zend_XmlRpc_Value_Base64</classname>
472 <entry>dateTime.iso8601</entry>
474 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME</constant>
477 <classname>Zend_XmlRpc_Value_DateTime</classname>
483 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY</constant>
486 <classname>Zend_XmlRpc_Value_Array</classname>
490 <entry>struct</entry>
492 <constant>Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT</constant>
495 <classname>Zend_XmlRpc_Value_Struct</classname>
504 <title>Automatic Conversion</title>
507 <classname>Zend_XmlRpc_Value</classname>
508 object, its value is set by a
509 <acronym>PHP</acronym>
511 <acronym>PHP</acronym>
512 type will be converted to the specified type using
513 <acronym>PHP</acronym>
514 casting. For example, if a string is given as a
516 <classname>Zend_XmlRpc_Value_Integer</classname>
517 object, it will be converted using
518 <command>(int)$value</command>
526 <sect2 id="zend.xmlrpc.client.requests-and-responses">
527 <title>Server Proxy Object</title>
529 Another way to call remote methods with the
530 <acronym>XML-RPC</acronym>
532 use the server proxy. This is a
533 <acronym>PHP</acronym>
534 object that proxies a remote
535 <acronym>XML-RPC</acronym>
536 namespace, making it work as close to a native
537 <acronym>PHP</acronym>
542 To instantiate a server proxy, call the
543 <methodname>getProxy()</methodname>
545 <classname>Zend_XmlRpc_Client</classname>
547 return an instance of
548 <classname>Zend_XmlRpc_Client_ServerProxy</classname>
550 Any method call on the server proxy object will be forwarded to
552 parameters may be passed like any other
553 <acronym>PHP</acronym>
557 <example id="zend.xmlrpc.client.requests-and-responses.example-1">
558 <title>Proxy the Default Namespace</title>
559 <programlisting language="php"><![CDATA[
560 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
562 $service = $client->getProxy(); // Proxy the default namespace
564 $hello = $service->test->sayHello(1, 2); // test.Hello(1, 2) returns "hello"
570 <methodname>getProxy()</methodname>
571 method receives an optional argument
572 specifying which namespace of the remote server to
574 does not receive a namespace, the default namespace will be
576 next example, the 'test' namespace
580 <example id="zend.xmlrpc.client.requests-and-responses.example-2">
581 <title>Proxy Any Namespace</title>
582 <programlisting language="php"><![CDATA[
583 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
585 $test = $client->getProxy('test'); // Proxy the "test" namespace
587 $hello = $test->sayHello(1, 2); // test.Hello(1,2) returns "hello"
592 If the remote server supports nested namespaces of any depth,
593 these can also be used
594 through the server proxy. For example, if
595 the server in the example above had a method
596 <command>test.foo.bar()</command>
597 , it could be called as
598 <command>$test->foo->bar()</command>
603 <sect2 id="zend.xmlrpc.client.error-handling">
604 <title>Error Handling</title>
606 Two kinds of errors can occur during an
607 <acronym>XML-RPC</acronym>
609 <acronym>HTTP</acronym>
611 <acronym>XML-RPC</acronym>
613 <classname>Zend_XmlRpc_Client</classname>
614 recognizes each and provides the ability
615 to detect and trap them independently.
618 <sect3 id="zend.xmlrpc.client.error-handling.http">
619 <title>HTTP Errors</title>
623 <acronym>HTTP</acronym>
624 error occurs, such as the remote
625 <acronym>HTTP</acronym>
627 <emphasis>404 Not Found</emphasis>
629 <classname>Zend_XmlRpc_Client_HttpException</classname>
633 <example id="zend.xmlrpc.client.error-handling.http.example-1">
634 <title>Handling HTTP Errors</title>
636 <programlisting language="php"><![CDATA[
637 $client = new Zend_XmlRpc_Client('http://foo/404');
641 $client->call('bar', array($arg1, $arg2));
643 } catch (Zend_XmlRpc_Client_HttpException $e) {
645 // $e->getCode() returns 404
646 // $e->getMessage() returns "Not Found"
653 Regardless of how the
654 <acronym>XML-RPC</acronym>
656 <classname>Zend_XmlRpc_Client_HttpException</classname>
659 <acronym>HTTP</acronym>
664 <sect3 id="zend.xmlrpc.client.error-handling.faults">
665 <title>XML-RPC Faults</title>
669 <acronym>XML-RPC</acronym>
670 fault is analogous to a
671 <acronym>PHP</acronym>
672 exception. It is a special type returned from an
673 <acronym>XML-RPC</acronym>
675 call that has both an error code and an error message.
676 <acronym>XML-RPC</acronym>
677 faults are handled differently depending on the context of how the
678 <classname>Zend_XmlRpc_Client</classname>
684 <methodname>call()</methodname>
686 proxy object is used, an
687 <acronym>XML-RPC</acronym>
688 fault will result in a
689 <classname>Zend_XmlRpc_Client_FaultException</classname>
691 The code and message of the exception will map directly to
693 respective values in the original
694 <acronym>XML-RPC</acronym>
699 <example id="zend.xmlrpc.client.error-handling.faults.example-1">
700 <title>Handling XML-RPC Faults</title>
702 <programlisting language="php"><![CDATA[
703 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
707 $client->call('badMethod');
709 } catch (Zend_XmlRpc_Client_FaultException $e) {
711 // $e->getCode() returns 1
712 // $e->getMessage() returns "Unknown method"
720 <methodname>call()</methodname>
722 para realizar la petición,
723 <classname>Zend_XmlRpc_Client_FaultException</classname>
724 será lanzado como error. Un objeto
725 <classname>Zend_XmlRpc_Response</classname>
727 error estará disponible llamando a
728 <methodname>getLastResponse()</methodname>
734 <methodname>doRequest()</methodname>
736 usado para realizar una petición, no lanzará una excepción. En
739 <classname>Zend_XmlRpc_Response</classname>
741 el error. Esto puede comprobarse con
742 <methodname>isFault()</methodname>
744 <classname>Zend_XmlRpc_Response</classname>
751 <sect2 id="zend.xmlrpc.client.introspection">
752 <title>Server Introspection</title>
755 <acronym>XML-RPC</acronym>
756 servers support the de facto introspection methods
758 <acronym>XML-RPC</acronym>
759 <emphasis>system.</emphasis>
761 <classname>Zend_XmlRpc_Client</classname>
762 provides special support for servers with
768 <classname>Zend_XmlRpc_Client_ServerIntrospection</classname>
770 retrieved by calling the
771 <methodname>getIntrospector()</methodname>
773 <classname>Zend_XmlRpcClient</classname>
774 . It can then be used to perform introspection
775 operations on the server.
779 <sect2 id="zend.xmlrpc.client.request-to-response">
780 <title>From Request to Response</title>
783 <methodname>call()</methodname>
785 <classname>Zend_XmlRpc_Client</classname>
786 builds a request object
788 <classname>Zend_XmlRpc_Request</classname>
789 ) and sends it to another method,
790 <methodname>doRequest()</methodname>
791 , that returns a response object
793 <classname>Zend_XmlRpc_Response</classname>
799 <methodname>doRequest()</methodname>
800 method is also available for use directly:
803 <example id="zend.xmlrpc.client.request-to-response.example-1">
804 <title>Processing Request to Response</title>
806 <programlisting language="php"><![CDATA[
807 $client = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');
809 $request = new Zend_XmlRpc_Request();
810 $request->setMethod('test.sayHello');
811 $request->setParams(array('foo', 'bar'));
813 $client->doRequest($request);
815 // $client->getLastRequest() returns instanceof Zend_XmlRpc_Request
816 // $client->getLastResponse() returns instanceof Zend_XmlRpc_Response
822 <acronym>XML-RPC</acronym>
823 method call is made by the client through any
825 <methodname>call()</methodname>
827 <methodname>doRequest()</methodname>
828 method, or server proxy, the last request
829 object and its resultant response object will
832 <methodname>getLastRequest()</methodname>
834 <methodname>getLastResponse()</methodname>
839 <sect2 id="zend.xmlrpc.client.http-client">
840 <title>HTTP Client and Testing</title>
843 In all of the prior examples, an
844 <acronym>HTTP</acronym>
845 client was never specified.
846 When this is the case, a new instance of
847 <classname>Zend_Http_Client</classname>
848 will be created with its default
850 <classname>Zend_XmlRpc_Client</classname>
856 <acronym>HTTP</acronym>
857 client can be retrieved at any time with the
858 <methodname>getHttpClient()</methodname>
859 method. For most cases, the default
860 <acronym>HTTP</acronym>
861 client will be sufficient. However, the
862 <methodname>setHttpClient()</methodname>
863 method allows for a different
864 <acronym>HTTP</acronym>
865 client instance to be injected.
870 <methodname>setHttpClient()</methodname>
871 is particularly useful for unit testing.
872 When combined with the
873 <classname>Zend_Http_Client_Adapter_Test</classname>
875 services can be mocked out for testing. See the unit tests for
876 <classname>Zend_XmlRpc_Client</classname>
877 for examples of how to do this.