15.2. Zend_XmlRpc_Client

15.2.1. Introdução

A forma de utilização do Zend_XmlRpc_Client é muito similar a dos objetos SoapClient (extensão SOAP web service). Você pode simplesmente chamar os procedimentos de serviço do XML-RPC como métodos de Zend_XmlRpc_Client . Especifique o endereço completo do serviço para o construtor do Zend_XmlRpc_Client.

Exemplo 15.1. Uma requisição XML-RPC básica

<?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() );

?>
            
[Nota] Nota
Zend_XmlRpc_Client tenta, na medida do possível, utilizar métodos remotos como se fossem nativos. Se um método remoto contiver namespaces, como por exemplo system.listMethods() , a chamada é feita usando encadeamento de objetos em PHP: $server->system->listMethods() .

15.2.2. Usando parâmetros

Alguns procedimentos de serviço XML-RPC requerem parâmetros, os parâmetros necessários são passados, como parâmetros, para o método Zend_XmlRpc_Client. Os parâmetros do procedimento XML-RPC devem ser de tipos de dados específicos ao XML-RPC. Os parâmetros podem ser passsados de duas maneiras: tipos nativos do PHP e objetos Zend_XmlRpc_Value que representam os tipos XML-RPC.

15.2.2.1. Passando variáveis nativas como parâmetros em PHP

Um parâmetro passado como variável nativa do PHP, pode ser uma string, um inteiro, um flutuante, um boleano, um array ou um objeto. Neste caso, cada tipo PHP nativo irá ser automaticamente detectado e convertido em um tipo XML-RPC, de acordo com a tabela abaixo:

Tabela 15.1. Conversão de valores nativos do PHP para tipos XML-RPC

Tipos nativos do PHP Tipos XML-RPC
inteiro int
double double
boleano boolean
string string
array array
array associativo struct
objeto 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);
...
            

15.2.2.2. Passando objetos Zend_XmlRpc_Value como parâmetros

Parameters passados como objetos Zend_XmlRpc_Value. Você pode criar uma das instâncias de Zend_XmlRpc_Value para especificar o tipo XML-RPC exato dos seus parâmetros. As razões principais para especificar explicitamente os tipos XML-RPC são:

  • Quando você quer assegurar que o tipo correto do parâmetro seja passado ao procedimento (ex: o procedimento exige um inteiro e você pode receber o parâmetro do array $_GET como string)
  • Quando o procedimento exige um tipo datetime ou um base64 (que não são tipos nativos do PHP).
  • Quando a existe a possibilidade da conversão automática falhar (ex: você quer passar uma estrutura XML-RPC vazia como parâmetro. Estruturas vazias são representadas como arrays vazios em PHP, mas, se você fornecer um array vazio como parãmetro ele irá ser automaticamente convertido para um array XML-RPC, desde que não seja um array associativo)

Existem duas maneiras de criar um objeto Zend_XmlRpc_Value object: a maneira explícita (chamando o construtor do objeto) ou usando a função estática Zend_XmlRpc_Value::getXmlRpcValue() que irá requerer uma constante XML-RPC.

Tabela 15.2. Objeto Zend_XmlRpc_Value representando os tipos XML-RPC

Tipo XML-RPC Constante de comparação Zend_XmlRpc_Value Objeto Zend_XmlRpc_Value
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);
...
            
[Nota] Nota
O valor do parâmetro é cedido por uma variável PHP mas irá ser convertido para o tipo específico usando as técnicas de conversão do PHP (ex: se uma string é informada como um valor para o objeto Zend_XmlRpc_Value_Integer , ele irá ser convertido usando (int)$value ).

15.2.2.3. Analisando uma string XML contida em um parâmetro XML-RPC

Este método de passagem por parâmetros é usado internamente no pacote Zend_XmlRpc e seu uso não é recomendado.

Se você tiver necessidade de usar este método, você deve usar a função estática Zend_XmlRpc_Value::getXmlRpcValue() para analisar uma string XML em um objeto Zend_XmlRpc_Value que representa o tipo XML-RPC correspondente. A função Zend_XmlRpc_Value::getXmlRpcValue() deve receber dois parâmetros: a string XML e a constante Zend_XmlRpc_Value::XML_STRING.

15.2.3. Indicando o tipo dos parâmetros

A principal diferença entre XML-RPC e web services SOAP é o arquivo WSDL. O protocolo SOAP usualmente possui um arquivo WSDL que descreve a interface para o web service. De acordo com esta interface, o cliente SOAP conhece os tipos de parâmetros que devem ser enviados ao servidor e quais são os tipos dos valores de retorno. Sem o arquivo WSDL, o usuário pode enfrentar problemas para descobrir quais são os tipos.

O solução do protocolo XML-RPC usa um procedimento de serviço especial chamado system.methodSignature. Este procedimento toma o nome do procedimento como um parâmetro e retorna a assinatura de um dado procedimento. A assinatura contém os respectivos tipos do parâmetro requerido e do valor de retorno do procedimento.

[Nota] Nota
Nem todos os servidores XML-RPC suportam o procedimento especial system.methodSignature , e consequentemente, não suportam também a indicação de tipo.

O Zend_XmlRpc_Client implementa uma gama de tipos de arquivos WSDL para servidores XML-RPC usando o procedimento system.methodSignature. Se solicitado, Zend_XmlRpc_Client irá requisitar uma lista de todos os procedimentos de um servidor XML-RPC, incluindo todas as assinaturas destes procedimentos. Todos esses dados serão gravados em um arquivo XML (similar ao arquivo SOAP WSDL). Quando o mesmo servidor XML-RPC for utilizado novamente, o usuário pode fornecer o arquivo XML e o Zend_XmlRpc_Client irá indicar o tipo de todos os parâmetros para os procedimentos requisitados, de acordo com suas assinaturas.

O arquivo XML contendo as assinaturas dos procedimentos é criado chamando-se a função Zend_XmlRpc_Client::__getMethodsXml() (a função retorna uma string XML contendo todos os dados das assinaturas). Para selecionar um arquivo XML de assinaturas, o usuário pode passar os dados XML como um parâmetro para o construtor Zend_XmlRpc_Client ou chamar a função Zend_XmlRpc_Client::__setMethodsXml().

Exemplo 15.2. Chamando um serviço XML-RPC com indicação de tipo

<?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);
?>
            

15.2.4. Obtendo a resposta

O procedimento retorna um valor de um tipo XML-RPC. O método Zend_XmlRpc_Client que chama o procedimento XML-RPC retorna um tipo nativo do PHP que foi convertido a partir de um tipo XML-RPC retornado.

Você pode usar a função Zend_XmlRpc_Client::__getResponse() para recuperar o valor de retorno do procedimento requisitado. A função __getResponse() recebe um parâmetro que indica o tipo do valor de retorno. As opções de resposta são:

  • Zend_XmlRpc_Client::RESPONSE_PHP_NATIVE - Devolve o valor de retorno do procedimento convertido para um tipo nativo do PHP (converte o tipo XML-RPC em um tipo PHP).
  • Zend_XmlRpc_Client::RESPONSE_XML_STRING - Retorna a string XML representando a resposta XML-RPC.
  • Zend_XmlRpc_Client::RESPONSE_ZXMLRPC_OBJECT - Retorna um objeto Zend_XmlRpc_Value object que representa o tipo XML-RPC retornado.
...
$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
...