Skip to content

13. Exercice IMPOTS avec XML

Dans cet exercice déjà étudié de nombreuses fois, le serveur renvoie les résultats au client sous la forme d'un flux XML.

13.1. Le serveur (impots_05B_web)

Le service web de calcul de l'impôt écrit précédemment a une architecture en couches :

Dans l'exemple précédent, le service web envoyait à ses clients l'une des deux lignes suivantes :

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

Ce n'est pas un document XML bien formé car il n'a pas de balise racine. Le nouveau service web enverra sa réponse sous la forme suivante :

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

ou

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

Dans les deux cas, la réponse est un document XML bien formé qui peut être exploité par le module [simpleXML].

Dans le schéma à trois couches, seule la couche [web] doit être modifiée. Son code [impots_05B_web] devient le suivant :


<?php

// couche métier
require_once "impots_05_metier.php";

// gestion des erreurs
ini_set("display_errors", "off");

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

// ------------------------------------------------------------------------------
// le service web des impôts
// définition des constantes
$HOTE = "localhost";
$PORT = 3306;
$BASE = "dbimpots";
$USER = "root";
$PWD = "";
// les données nécessaires au calcul de l'impôt ont été placées dans la table mysqL $TABLE
// appartenant à la base $BASE. La table a la structure suivante
// limites decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
// les paramètres des personnes imposables (statut marital, nombre d'enfants, salaire annuel)
// sont envoyés par le client sous la forme params=statut marital, nombre d'enfants, salaire annuel
// les résultats (statut marital, nombre d'enfants, salaire annuel, impôt à payer) sont renvoyés au client
// sous la forme <impot>impot</impot>
// ou sous la forme <erreur>erreur</erreur>, si les paramètres sont invalides
// on récupère la couche [métier] dans la session
session_start();
if (!isset($_SESSION['metier'])) {
// instanciation de la couche [dao] et de la couche [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'];

// on récupère la ligne envoyée par le client
$params = utf8_encode(htmlspecialchars(strtolower(trim($_POST['params']))));
//print "paramètres reçus --> $params\n";
$items = explode(",", $params);
// il ne doit y avoir que 3 paramètres
if (count($items) != 3) {
  print "<reponse><erreur>[$params] : nombre de paramètres invalides</erreur></reponse>\n";
  exit;
}//if
// le premier paramètre (statut marital) doit être oui/non
$marié = trim($items[0]);
if ($marié != "oui" and $marié != "non") {
  print "<reponse><erreur>[$params] : 1er paramètre invalide</erreur></reponse>\n";
  exit;
}//if
// le second paramètre (nbre d'enfants) doit être un nombre entier
if (!preg_match("/^\s*(\d+)\s*$/", $items[1], $champs)) {
  print "<reponse><erreur>[$params] : 2ième paramètre invalide</erreur></reponse>\n";
  exit;
}//if
$enfants = $champs[1];
// le troisième paramètre (salaire) doit être un nombre entier
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];
// on calcule l'impôt
$impôt = $metier->calculerImpot($marié, $enfants, $salaire);
// on renvoie le résultat
print "<reponse><impot>$impôt</impot></reponse>\n";
// fin
exit;

Le format de la réponse du service web est modifiée aux lignes 35, 47, 53, 58, 64 et 71.

13.2. Le client (client_impots_05b_web)

Le client est modifié pour tenir compte du nouveau format de la réponse. On utilise [simpleXML] pour traiter celle-ci :


<?php

// client impôts
// gestion des erreurs
ini_set("display_errors", "off");

// ---------------------------------------------------------------------------------
// une classe de fonctions utilitaires
class Utilitaires {
...
}

// main -----------------------------------------------------
// définition des constantes
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
// données serveur
$HOTE = "localhost";
$PORT = 80;
$urlServeur = "/exemples-web/impots_05B_web.php";

...
exit;

function calculerImpot($HOTE, $PORT, $urlServeur, &$cookie, $params) {
  // connecte le client à ($HOTE,$PORT,$urlServeur)
// envoie le cookie $cookie si celui-ci est non vide. $cookie est passé par référence
// envoie $params au serveur
// exploite la ligne du résultat
...
  // lecture ligne du résultat
  $ligne = fgets($connexion, 1000);
  // on ferme la connexion
  fclose($connexion);
  // calcul résultat
  $xml = new SimpleXMLElement($ligne);
  $erreur = isset($xml->erreur) ? $xml->erreur : "";
  $impôt = isset($xml->impot) ? $xml->impot : "";
  // retour
  return array($erreur, $impôt);
}
  • ligne 32 : la réponse du serveur est lue. C'est un document XML.
  • ligne 36 : un objet SimpleXML est construit à partir du document XML reçu.
  • ligne 37 : l'éventuel message d'erreur
  • ligne 38 : l'éventuel montant de l'impôt