13. Tax Calculation: Exercise with XML
In this exercise, which we have already studied many times, the server returns the results to the client in the form of an XML stream.
13.1. The server (impots_05B_web)
The tax calculation web service written earlier has a layered architecture:
![]() |
In the previous example, the web service sent one of the following two lines to its clients:
This is not a well-formed XML document because it lacks a root tag. The new web service will send its response in the following format:
or
In both cases, the response is a well-formed XML document that can be processed by the [simpleXML] module.
In the three-tier architecture, only the [web] layer needs to be modified. Its code [impots_05B_web] becomes the following:
<?php
// business layer
require_once "impots_05_metier.php";
// error management
ini_set("display_errors", "off");
// uTF-8 header
header("Content-Type: text/plain; charset=utf-8");
// ------------------------------------------------------------------------------
// tax web service
// definition of constants
$HOTE = "localhost";
$PORT = 3306;
$BASE = "dbimpots";
$USER = "root";
$PWD = "";
// the data required to calculate the tax has been placed in table mysqL $TABLE
// belonging to the $BASE database. The table has the following structure
// limits decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
// taxable person parameters (marital status, number of children, annual salary)
// are sent by the customer in the form params=marital status, number of children, annual salary
// results (marital status, number of children, annual salary, tax payable) are returned to the customer
// in the form <impot>impot</impot>
// or as <error>error</error>, if parameters are invalid
// retrieve the [business] layer in the session
session_start();
if (!isset($_SESSION['metier'])) {
// instantiation of the [dao] layer and the [business] layer
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'];
// retrieve the line sent by the client
$params = utf8_encode(htmlspecialchars(strtolower(trim($_POST['params']))));
//print "parameters received --> $params\n";
$items = explode(",", $params);
// there must be only 3 parameters
if (count($items) != 3) {
print "<reponse><erreur>[$params] : nombre de paramètres invalides</erreur></reponse>\n";
exit;
}//if
// first parameter (marital status) must be yes/no
$marié = trim($items[0]);
if ($marié != "oui" and $marié != "non") {
print "<reponse><erreur>[$params] : 1er paramètre invalide</erreur></reponse>\n";
exit;
}//if
// the second parameter (number of children) must be an integer
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];
// the third parameter (salary) must be an integer
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];
// tax calculation
$impôt = $metier->calculerImpot($marié, $enfants, $salaire);
// return the result
print "<reponse><impot>$impôt</impot></reponse>\n";
// end
exit;
The format of the web service response is modified on lines 35, 47, 53, 58, 64, and 71.
13.2. The client (client_impots_05b_web)
The client is modified to account for the new response format. We use [simpleXML] to process it:
<?php
// tax client
// error management
ini_set("display_errors", "off");
// ---------------------------------------------------------------------------------
// a class of utility functions
class Utilitaires {
...
}
// main -----------------------------------------------------
// definition of constants
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
// server data
$HOTE = "localhost";
$PORT = 80;
$urlServeur = "/exemples-web/impots_05B_web.php";
...
exit;
function calculerImpot($HOTE, $PORT, $urlServeur, &$cookie, $params) {
// connects client to ($HOTE,$PORT,$urlServeur)
// sends the $cookie cookie if it is non-empty. $cookie is passed by reference
// sends $params to the server
// exploits the result line
...
// read line result
$ligne = fgets($connexion, 1000);
// close the connection
fclose($connexion);
// result calculation
$xml = new SimpleXMLElement($ligne);
$erreur = isset($xml->erreur) ? $xml->erreur : "";
$impôt = isset($xml->impot) ? $xml->impot : "";
// return
return array($erreur, $impôt);
}
- line 32: the server's response is read. It is an XML document.
- line 36: A SimpleXML object is constructed from the received XML document.
- line 37: any error message
- line 38: the tax amount, if any
