Skip to content

13. Esercizio IMPOTS con XML

In questo esercizio, già studiato numerose volte, il server restituisce i risultati al client sotto forma di un flusso XML.

13.1. Il server (impots_05B_web)

Il servizio web per il calcolo delle imposte scritto in precedenza presenta un’architettura a livelli:

Nell’esempio precedente, il servizio web inviava ai propri clienti una delle due righe seguenti:

<erreur>message d'erreur</erreur>
<impot>montant de l'impôt</impot>

Questo non è un documento XML ben formato poiché non presenta un tag radice. Il nuovo servizio web invierà la propria risposta nella forma seguente:

<reponse><erreur>message d'erreur</erreur></reponse>

oppure

<reponse><impot>montant de l'impôt</impot></reponse>

In entrambi i casi, la risposta è un documento XML ben formato che può essere elaborato dal modulo [simpleXML].

Nello schema a tre livelli, deve essere modificato solo il livello [web]. Il suo codice [impots_05B_web] diventa il seguente:


<?php

// livello applicativo
require_once "impots_05_metier.php";

// gestione degli errori
ini_set("display_errors", "off");

// intestazione UTF-8
header("Content-Type: text/plain; charset=utf-8");

// ------------------------------------------------------------------------------
// il servizio web delle imposte
// definizione delle costanti
$HOTE = "localhost";
$PORT = 3306;
$BASE = "dbimpots";
$USER = "root";
$PWD = "";
// i dati necessari per il calcolo dell'imposta sono stati inseriti nella tabella mysqL $TABLE
// appartenente al database $BASE. La tabella presenta la seguente struttura
// limiti decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
// i parametri dei soggetti imponibili (stato civile, numero di figli, stipendio annuo)
// vengono inviati dal cliente nel formato params=stato civile, numero di figli, stipendio annuo
// i risultati (stato civile, numero di figli, stipendio annuo, imposta da pagare) vengono restituiti al cliente
// nel formato <imposta>imposta</imposta>
// oppure nel formato <errore>errore</errore>, se i parametri non sono validi
// viene recuperato il livello [métier] nella sessione
session_start();
if (!isset($_SESSION['metier'])) {
// istanziazione del livello [dao] e del livello [métier]
  try {
    $_SESSION['metier'] = new ImpotsMetier(new ImpotsDaoWithMySQL($HOTE, $PORT, $BASE, $USER, $PWD));
  } catch (ImpotsException $ie) {
    print "<reponse><erreur>Erreur : " . utf8_encode($ie->getMessage() . "</erreur></reponse>");
    exit;
  }
}
$metier = $_SESSION['metier'];

// si recupera la riga inviata dal cliente
$params = utf8_encode(htmlspecialchars(strtolower(trim($_POST['params']))));
//print "parametri ricevuti --> $params\n";
$items = explode(",", $params);
// devono esserci solo 3 parametri
if (count($items) != 3) {
  print "<reponse><erreur>[$params] : nombre de paramètres invalides</erreur></reponse>\n";
  exit;
}//if
// il primo parametro (stato civile) deve essere sì/no
$marié = trim($items[0]);
if ($marié != "oui" and $marié != "non") {
  print "<reponse><erreur>[$params] : 1er paramètre invalide</erreur></reponse>\n";
  exit;
}//if
// il secondo parametro (numero di figli) deve essere un numero intero
if (!preg_match("/^\s*(\d+)\s*$/", $items[1], $champs)) {
  print "<reponse><erreur>[$params] : 2ième paramètre invalide</erreur></reponse>\n";
  exit;
}//se
$enfants = $champs[1];
// il terzo parametro (stipendio) deve essere un numero intero
if (!preg_match("/^\s*(\d+)\s*$/", $items[2], $champs)) {
  print "<reponse><erreur>[$params] : 3ième paramètre invalide</erreur></reponse>\n";
  exit;
}//if
$salaire = $champs[1];
// si calcola l'imposta
$impôt = $metier->calculerImpot($marié, $enfants, $salaire);
// si restituisce il risultato
print "<reponse><impot>$impôt</impot></reponse>\n";
// fine
exit;

Il formato della risposta del servizio web viene modificato alle righe 35, 47, 53, 58, 64 e 71.

13.2. Il client (client_impots_05b_web)

Il client viene modificato per tenere conto del nuovo formato della risposta. Per elaborarla si utilizza [simpleXML]:


<?php

// cliente imposte
// gestione degli errori
ini_set("display_errors", "off");

// ---------------------------------------------------------------------------------
// una classe di funzioni di utilità
class Utilitaires {
...
}

// main -----------------------------------------------------
// definizione delle costanti
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
// dati del server
$HOTE = "localhost";
$PORT = 80;
$urlServeur = "/exemples-web/impots_05B_web.php";

...
exit;

function calculerImpot($HOTE, $PORT, $urlServeur, &$cookie, $params) {
  // connette il client a ($HOTE,$PORT,$urlServeur)
// invia il cookie $cookie se questo non è vuoto. $cookie viene passato per riferimento
// invia $params al server
// elabora la riga del risultato
...
  // lettura della riga del risultato
  $ligne = fgets($connexion, 1000);
  // si chiude la connessione
  fclose($connexion);
  // calcolo del risultato
  $xml = new SimpleXMLElement($ligne);
  $erreur = isset($xml->erreur) ? $xml->erreur : "";
  $impôt = isset($xml->impot) ? $xml->impot : "";
  // ritorno
  return array($erreur, $impôt);
}
  • riga 32: viene letta la risposta del server. Si tratta di un documento XML.
  • riga 36: viene creato un oggetto SimpleXML a partire dal documento XML ricevuto.
  • riga 37: l'eventuale messaggio di errore
  • riga 38: l'eventuale importo dell'imposta