4. Tipos de Dados Simples

Até agora os serviços que vimos usaram apenas o tipo de dados string. Vamos ver agora como podemos usar os outros tipos de dados simples: números inteiros, números reais e valores lógicos (booleanos).

Vamos criar um serviço que disponibiliza duas funcionalidades, a soma e a subtração de dois valores inteiros, e que, para qualquer um deles, dá como resultado um valor inteiro (nos exemplos seguintes e para uma maior clareza não iremos incluir o tratamento de erros, algo que o programador deverá fazer quando implementar um serviço a sério).

Exemplo 2.12. O servidor: serv-aritmetica.php

<?php
require_once('../lib/nusoap.php');

$server = new soap_server;

// Register the method to expose
$server->register( 'soma', 
                   array('n1'=>'xsd:integer', 'n2'=>'xsd:integer'),
                   array('res'=>'xsd:integer' ),
                   'uri:ws.di.uminho.pt/Aritmetica',
                   'uri:ws.di.uminho.pt/Aritmetica/soma',
                   'rpc',    
                   'encoded');
                   
$server->register( 'sub',  
                   array('n1'=>'xsd:integer', 'n2'=>'xsd:integer'),
                   array('res'=>'xsd:integer' ),
                   'uri:ws.di.uminho.pt/Aritmetica',
                   'uri:ws.di.uminho.pt/Aritmetica/soma',
                   'rpc',    
                   'encoded');

function soma($n1, $n2) {
    return $n1+$n2;
}

function sub($n1, $n2) {
    return $n1-$n2;
}

// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($HTTP_RAW_POST_DATA);
?>

Note a declaração dos argumentos e do resultado com o tipo xsd:integer.


Para efeitos de validação vamos codificar um cliente que invoca o serviço e que depois imprime o resultado e indica de que tipo é este (vamos usar a função do PHP gettype(variável) que retorna o tipo da variável argumento).

Exemplo 2.13. O cliente: client-aritmetica.php

<?php
require_once('../lib/nusoap.php');

$num1 = $_REQUEST['n1'];
$num2 = $_REQUEST['n2'];

// Server Location
$location = 'http://localhost:8888/nusoap-0.9.5/Soma2nums/serv-aritmetica.php';

$client = new nusoap_client( $location, false);

// Call the SOAP method
$res1 = $client->call('soma', array('n1' => $num1, 'n2' => $num2 ));
$res2 = $client->call('sub', array('n1' => $num1, 'n2' => $num2 ));

// Display the result
echo $num1 ." + ". $num2 ." = ". $res1 ."<br/>";
echo "Este resultado é do tipo: ". gettype($res1) ."<br/>";
echo $num1 ." - ". $num2 ." = ". $res2 ."<br/>";
echo "Este resultado é do tipo: ". gettype($res2) ."<br/>";
?>

Após a invocação do serviço por parte do cliente o resultado retornado é este:

Figura 2.2. Invocação do cliente: client-aritmetica.php

Invocação do cliente: client-aritmetica.php

Vamos agora alterar o serviço para fornecer duas funcionalidades extra, a multiplicação e a divisão. E vamos indicar que estas funcionalidades recebem dois números reais e dão como resultado um número real.

O servidor ficaria assim:

Exemplo 2.14. O servidor: serv-aritmetica2.php

...
$server->register( 'mul',  
                   array('n1'=>'xsd:float', 'n2'=>'xsd:float'),
                   array('res'=>'xsd:float' ),
                   'uri:ws.di.uminho.pt/Aritmetica',
                   'uri:ws.di.uminho.pt/Aritmetica/mul',
                   'rpc',    
                   'encoded');
                   
$server->register( 'div',  
                   array('n1'=>'xsd:float', 'n2'=>'xsd:float'),
                   array('res'=>'xsd:float' ),
                   'uri:ws.di.uminho.pt/Aritmetica',
                   'uri:ws.di.uminho.pt/Aritmetica/div',
                   'rpc',    
                   'encoded');  
...
function div($n1, $n2) {
    return $n1/$n2;
}

function mul($n1, $n2) {
    return $n1*$n2;
}
...

E vamos alterar o cliente para agora consumir as quatro funcionalidades, indicando o tipo do resultado de todas.

Exemplo 2.15. O cliente: client-aritmetica2.php

<?php
require_once('../lib/nusoap.php');

$num1 = $_REQUEST['n1'];
$num2 = $_REQUEST['n2'];

// Server Location
$location = 'http://localhost:8888/nusoap-0.9.5/Soma2nums/serv-aritmetica2.php';

$client = new nusoap_client( $location, false);
$namespace = 'uri:ws.di.uminho.pt/Aritmetica';
$soapaction = 'uri:ws.di.uminho.pt/Aritmetica/mul';

// Call the SOAP method
$res1 = $client->call('soma', array('n1' => $num1, 'n2' => $num2 ), $namespace, $soapaction );
$res2 = $client->call('sub', array('n1' => $num1, 'n2' => $num2 ), $namespace, $soapaction );
$res3 = $client->call('mul', array('n1' => $num1, 'n2' => $num2 ), $namespace, $soapaction );
$res4 = $client->call('div', array('n1' => $num1, 'n2' => $num2 ), $namespace, $soapaction );

// Display the result
echo $num1 ." + ". $num2 ." = ". $res1 ."<br/>";
echo "Este resultado é do tipo: ". gettype($res1) ."<br/>";
echo $num1 ." - ". $num2 ." = ". $res2 ."<br/>";
echo "Este resultado é do tipo: ". gettype($res2) ."<br/>";
echo $num1 ." * ". $num2 ." = ". $res3 ."<br/>";
echo "Este resultado é do tipo: ". gettype($res3) ."<br/>";
echo $num1 ." / ". $num2 ." = ". $res4 ."<br/>";
echo "Este resultado é do tipo: ". gettype($res4) ."<br/>";                        
?>

A seguir apresentam-se duas imagens com o resultado de duas execuções deste cliente: na primeira com parâmetros inteiros e na segunda com parâmetros reais.

Figura 2.3. Invocação do cliente com parâmetros inteiros

Invocação do cliente com parâmetros inteiros

Note que os resultados devolvidos são todos inteiros. Isto acontece porque apesar de termos tipado os argumentos e os resultados das várias funcionalidades a classe NuSOAP não faz qualquer verificação de tipos delegando essa tarefa para o programador.

Figura 2.4. Invocação do cliente com parâmetros reais

Invocação do cliente com parâmetros reais

Nesta segunda situação, basta um dos argumentos ser real para que os resultados venham todos classificados como reais.

A seguir apresenta-se o pedido da última invocação, para o método div.

Exemplo 2.16. Pedido para o método div

Content-Type: text/xml; charset=ISO-8859-1
SOAPAction: ""
Content-Length: 522

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope 
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <ns4717:div xmlns:ns4717="uri:ws.di.uminho.pt/Aritmetica">
      <n1 xsi:type="xsd:string">4.6</n1>
      <n2 xsi:type="xsd:string">2</n2>
    </ns4717:div>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Neste pedido, o tipo dos argumentos é string, como são passados no URL o PHP assume automaticamente que são deste tipo. No entanto, este facto não irá afetar as operações do lado do servidor desde que os argumentos sejam o que devem ser. Como foi referido anteriormente qualquer verificação de tipos terá de ser feita pelo programador do lado do servidor ou do lado do cliente.

Apresenta-se a seguir a resposta a este pedido.

Exemplo 2.17. Resposta da chamada ao método div

HTTP/1.1 200 OK
Date: Mon, 17 Dec 2012 21:44:45 GMT
Server: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.6
X-Powered-By: PHP/5.3.6
X-SOAP-Server: NuSOAP/0.9.5 (1.123)
Content-Length: 504
Connection: close
Content-Type: text/xml; charset=ISO-8859-1

<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope 
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  <SOAP-ENV:Body>
    <ns1:divResponse xmlns:ns1="uri:ws.di.uminho.pt/Aritmetica">
      <return xsi:type="xsd:float">2.3</return>
    </ns1:divResponse>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>