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_business.php";
// error handling
ini_set("display_errors", "off");
// UTF-8 header
header("Content-Type: text/plain; charset=utf-8");
// ------------------------------------------------------------------------------
// the tax web service
// definition of constants
$HOST = "localhost";
$PORT = 3306;
$DATABASE = "dbimpots";
$USER = "root";
$PWD = "";
// The data needed to calculate the tax has been placed in the MySQL table $TABLE
// belonging to the $BASE database. The table has the following structure
// limits decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
// the parameters for taxable individuals (marital status, number of children, annual salary)
// are sent by the client in the form params=marital status, number of children, annual salary
// the results (marital status, number of children, annual salary, tax due) are returned to the client
// in the form <tax>tax</tax>
// or in the form <error>error</error>, if the parameters are invalid
// retrieve the [business] layer from the session
session_start();
if (!isset($_SESSION['business'])) {
// instantiate the [dao] layer and the [business] layer
try {
$_SESSION['metier'] = new ImpotsMetier(new ImpotsDaoWithMySQL($HOST, $PORT, $BASE, $USER, $PWD));
} catch (ImpotsException $ie) {
print "<response><error>Error: " . utf8_encode($ie->getMessage() . "</error></response>");
exit;
}
}
$job = $_SESSION['job'];
// 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 exactly 3 parameters
if (count($items) != 3) {
print "<response><error>[$params]: number of invalid parameters</error></response>\n";
exit;
}//if
// the first parameter (marital status) must be yes/no
$married = trim($items[0]);
if ($married != "yes" and $married != "no") {
print "<response><error>[$params]: Invalid first parameter</error></response>\n";
exit;
}//if
// the second parameter (number of children) must be an integer
if (!preg_match("/^\s*(\d+)\s*$/", $items[1], $fields)) {
print "<response><error>[$params]: Invalid second parameter</error></response>\n";
exit;
}//if
$children = $fields[1];
// the third parameter (salary) must be an integer
if (!preg_match("/^\s*(\d+)\s*$/", $items[2], $fields)) {
print "<response><error>[$params]: Invalid third parameter</error></response>\n";
exit;
}//if
$salary = $fields[1];
// calculate the tax
$tax = $occupation->calculateTax($married, $children, $salary);
// return the result
print "<response><tax>$tax</tax></response>\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 handling
ini_set("display_errors", "off");
// ---------------------------------------------------------------------------------
// a class of utility functions
class Utilities {
...
}
// main -----------------------------------------------------
// definition of constants
$DATA = "data.txt";
$RESULTS = "results.txt";
// server data
$HOST = "localhost";
$PORT = 80;
$serverUrl = "/web-examples/taxes_05B_web.php";
...
exit;
function calculateTax($HOST, $PORT, $serverUrl, &$cookie, $params) {
// connects the client to ($HOST, $PORT, $serverUrl)
// sends the $cookie if it is not empty. $cookie is passed by reference
// sends $params to the server
// processes the result line
...
// read the result line
$line = fgets($connection, 1000);
// close the connection
fclose($connection);
// calculate result
$xml = new SimpleXMLElement($line);
$error = isset($xml->error) ? $xml->error : "";
$tax = isset($xml->tax) ? $xml->tax : "";
// return
return array($error, $tax);
}
- 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
