17.2. Zend_XmlRpc_Client
Пред. | Глава 17. Zend_XmlRpc | След.

## 17.2. Zend_XmlRpc_Client

### 17.2.1. Introduction

Using the `Zend_XmlRpc_Client` is very similar to using `SoapClient` objects (SOAP web service extension). You can simply call the XML-RPC service procedures as `Zend_XmlRpc_Client` methods. Specify the service's full address in the `Zend_XmlRpc_Client` constructor.

Пример 17.1. A basic XML-RPC request

    <?php
    /**
     * Connect to framework.zend.com server and an array describing
     * the methods available.
     */
    require_once 'Zend/XmlRpc/Client.php';

    $server = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');

    print_r( $server->system->listMethods() );

    ?>

| Замечание
`Zend_XmlRpc_Client` attempts to make remote methods look as much like native methods as possible. If a remote method contains namespaces, such as `system.listMethods()` above, the call is made using object chaining in PHP: `$server->system->listMethods()`.

### 17.2.2. Using parameters

Some XML-RPC service procedures require parameters, the necessary parameters are passed as parameters for the `Zend_XmlRpc_Client` method. XML-RPC procedure parameters must be a specific XML-RPC type. Parameters can be passed in 2 ways: as PHP natives or `Zend_XmlRpc_Value` objects which represent XML-RPC types.

#### 17.2.2.1. Passing PHP native variables as parameters

Parameters passed as native PHP variables, meaning as a string, integer, float, boolean, array or an object. In this case, each PHP native type will be auto-detected and converted into one of the XML-RPC types according to this table:

Таблица 17.1. PHP native values convertion to XML-RPC types

PHP native type | XML-RPC type
--- | ---
integer | int
double | double
boolean | boolean
string | string
array | array
associative array | struct
object | array

    ...
    /** 2 parameters are passed in this procedure
     *  The first parameter is a string that will be auto-converted into an XML-RPC string type
     *  The second parameter is an assosiative array that will be converted into an XML-RPC struct
     */

    $p1 = 'parameter 1';
    $p2 = array('name' => 'Joe', 'age' => 30);

    $service->serviceProcedure($p1, $p2);
    ...

#### 17.2.2.2. Passing `Zend_XmlRpc_Value` objects as parameters

Parameters passed as `Zend_XmlRpc_Value` objects. You can create one of the `Zend_XmlRpc_Value` instances to specify the exact XML-RPC type of your parameters. The main reasons for explictly specifing the XML-RPC types are:

- When you want to make sure the correct parameter type is passed to the procedure (i.e. the procedure requires an integer and you may receive the parameter from the $_GET array as a string)
- When the procedure requires base64 or dateTime.iso8601 type (which doesn't exists as a PHP native type)
- When auto-convertion may fail (i.e. you want to pass an empty XML-RPC struct as a parameter. Empty structs are represented as empty arrays in PHP but, if you give an empty array as a parameter it will be auto-converted to an XML-RPC array since it's not an assosiative array)

There are 2 ways to create an `Zend_XmlRpc_Value` object: the explicit way (call the object's constructor) or using the `Zend_XmlRpc_Value::getXmlRpcValue()` static function with the required XML-RPC type constant.

Таблица 17.2. `Zend_XmlRpc_Value` object representing the XML-RPC types

XML-RPC type | Matching `Zend_XmlRpc_Value` constant | `Zend_XmlRpc_Value` object
--- | --- | ---
int | `Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER` | `Zend_XmlRpc_Value_Integer`
double | `Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE` | `Zend_XmlRpc_Value_Double`
boolean | `Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN` | `Zend_XmlRpc_Value_Boolean`
string | `Zend_XmlRpc_Value::XMLRPC_TYPE_STRING` | `Zend_XmlRpc_Value_String`
base64 | `Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64` | `Zend_XmlRpc_Value_Base64`
dateTime.iso8601 | `Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME` | `Zend_XmlRpc_Value_DateTime`
array | `Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY` | `Zend_XmlRpc_Value_Array`
struct | `Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT` | `Zend_XmlRpc_Value_Struct`

    ...
    /** 2 parameters are passed to this procedure
     *  The first parameter is an XML-RPC base64 type that is created using the static Zend_XmlRpc_Value::getXmlRpcValue() function
     *  The second parameter is an XML-RPC strcture that is created explictly
     */

    $p1 = ZXmlRpcValue::getXmlRpcValue('encoded string', Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64);
    $p2 = new Zend_XmlRpc_Value_Struct(array('name' => 'Joe', 'age' => 30));

    $service->serviceProcedure($p1, $p2);
    ...

| Замечание
The value of the parameter is still given in a PHP variable but will be converted to the specified type using PHP conversion techniques (i.e. if a string is given as a value to the `Zend_XmlRpc_Value_Integer` object, it will be converted using `(int)$value`).

#### 17.2.2.3. Parse an XML string into XML-RPC parameter

This method of passing parameters is used internaly in the `Zend_XmlRpc` package and it's not recommended.

If you still need to use this method, you should use the `Zend_XmlRpc_Value::getXmlRpcValue()` static function to parse an XML string into a `Zend_XmlRpc_Value` object which represents the corresponding XML-RPC type. The `Zend_XmlRpc_Value::getXmlRpcValue()` function should receive 2 parameters: the XML string and the `Zend_XmlRpc_Value::XML_STRING` constant.

### 17.2.3. Type hinting of parameters

The main difference between the XML-RPC and SOAP web services is the WSDL file. The SOAP protocol usualy has a WSDL file that describes the interface to the web service. According to this interface, the SOAP client knows what are the necessary parameter types it has to send to the server and what is the return value type. Without the WSDL file, the user might have a problem knowing these types.

The XML-RPC protocol solution uses a special procedure of the service called `system.methodSignature`. This procedure gets a procedure name as a parameter and returns the signature of the given procedure. The signature is the necessary parameter's type and return value type of that procedure.

| Замечание
Not all XML-RPC servers support the special `system.methodSignature` procedure, servers who don't support it cannot support type hinting.

The `Zend_XmlRpc_Client` implements a sort of 'WSDL' type file for XML-RPC servers using the `system.methodSignature` procedure. If requested, the `Zend_XmlRpc_Client` will request a list of all the procedures of an XML-RPC server, request all the signatures of those procedures, and keep all this data in an XML file (similar to the SOAP WSDL file). When using the same XML-RPC server again, the user can supply the XML file and the `Zend_XmlRpc_Client` will type hint all the parameters for the requested procedure according to their signatures.

The procedures signatures XML file is created by calling the `Zend_XmlRpc_Client::__getMethodsXml()` function (the function returns an XML string containing all the signature's data). To set an existing signatures XML file, the user can pass the XML data as a parameter in the `Zend_XmlRpc_Client` constructor or call the `Zend_XmlRpc_Client::__setMethodsXml()` function.

Пример 17.2. Calling an XML-RPC service with type hinting

    <?php
    /**
     * Connect to an XML-RPC server, and save it's signatures file (the XML-RPC eqvivilant to a SOAP WSDL file)
     */
    require_once 'Zend/XmlRpc/Client.php';

    $service = new Zend_XmlRpc_Client('http://www.example.org/xmlrpc');

    file_put_contents('/tmp/xmlrpc-signatures/example.xml', $service->__getMethodsXml());

    /* The $service object contains all the signatures of the XML-RPC server,
        when the serviceProcedure is called, its parameter ($param) is converted
        to the necessary type according to the procedure's signature.
     */
    $service->serviceProcedure($param);
    ?>

    <?php
    /**
     * Connect to an XML-RPC server, using an existing signature file, we make sure
     * that the type of the parameters passed to the procedures are of the necessary type
     */
    require_once 'Zend/XmlRpc/Client.php';

    $signature_file_xml = file_get_contents('/tmp/xmlrpc-signatures/example.xml');
    $service = new Zend_XmlRpc_Client('http://www.example.org/xmlrpc', 'namespace', $signature_file_xml);

    /* The $service object contains all the signatures of the XML-RPC server,
        when the serviceProcedure is called, its parameter ($param) is converted
        to the necessary type according to the procedure's signature.
     */
    $service->serviceProcedure($param);
    ?>

### 17.2.4. Getting the response

The XML-RPC procedure returns a value in an XML-RPC type. The `Zend_XmlRpc_Client` method which calls the XML-RPC procedure returns a PHP native type that was converted from the returned XML-RPC type.

You can use the `Zend_XmlRpc_Client::__getResponse()` function to retrieve the return value of the requested procedure. The `__getResponse()` function receives a parameter which indicates the type of the return value. The response options are:

- `Zend_XmlRpc_Client::RESPONSE_PHP_NATIVE` - Return the procedure return value as a PHP native type (convert the XML-RPC type into a PHP type).
- `Zend_XmlRpc_Client::RESPONSE_XML_STRING` - Return the XML string representation of the XML-RPC response.
- `Zend_XmlRpc_Client::RESPONSE_ZXMLRPC_OBJECT` - Return a `Zend_XmlRpc_Value` object which represents the returned XML-RPC type.

    ...
    $service->serviceProcedure();

    $response = $service->__getResponse();
    // $response is the PHP variable converted from the XML-RPC type return value

    $response = $service->__getResponse(ZXmlRpcClient::RESPONSE_XML_STRING);
    // $response is a string containing the XML representing the procedure return value

    $response = $service->__getResponse(ZXmlRpcClient::RESPONSE_ZXMLRPC_OBJECT);
    // $response is a Zend_XmlRpc_Value instance representing the XML-RPC type return value
    ...

Пред. | Уровень выше | След.
Глава 17. Zend_XmlRpc | Начало | Приложение A. Стандарт кодирования на PHP в Zend Framework'е