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:
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.
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.
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>