Skip to content

13. Ćwiczenie IMPOTS z wykorzystaniem XML

W tym ćwiczeniu, które analizowaliśmy już wielokrotnie, serwer zwraca wyniki do klienta w postaci strumienia XML.

13.1. Serwer (impots_05B_web)

Opisana wcześniej usługa internetowa do obliczania podatku ma architekturę warstwową:

W poprzednim przykładzie usługa internetowa wysyłała do swoich klientów jeden z dwóch następujących wierszy:

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

Nie jest to poprawnie sformułowany dokument XML, ponieważ nie zawiera on tagu głównego. Nowa usługa internetowa będzie wysyłać swoją odpowiedź w następującej postaci:

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

lub

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

W obu przypadkach odpowiedź jest poprawnie sformułowanym dokumentem XML, który może być przetworzony przez moduł [simpleXML].

W schemacie trójwarstwowym należy zmodyfikować jedynie warstwę [web]. Jej kod [impots_05B_web] przyjmuje następującą postać:


<?php

// warstwa biznesowa
require_once "impots_05_metier.php";

// obsługa błędów
ini_set("display_errors", "off");

// nagłówek UTF-8
header("Content-Type: text/plain; charset=utf-8");

// ------------------------------------------------------------------------------
// serwis internetowy urzędu skarbowego
// definicja stałych
$HOTE = "localhost";
$PORT = 3306;
$BASE = "dbimpots";
$USER = "root";
$PWD = "";
// dane niezbędne do obliczenia podatku zostały umieszczone w tabeli mysqL $TABLE
// należącej do bazy danych $BASE. Tabela ma następującą strukturę
// limity decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
// parametry osób podlegających opodatkowaniu (stan cywilny, liczba dzieci, roczne wynagrodzenie)
// są przesyłane przez klienta w postaci params=stan cywilny, liczba dzieci, roczne wynagrodzenie
// wyniki (stan cywilny, liczba dzieci, roczne wynagrodzenie, podatek do zapłaty) są zwracane klientowi
// w postaci <podatek>podatek</podatek>
// lub w postaci <błąd>błąd</błąd>, jeśli parametry są nieprawidłowe
// w sesji pobierana jest warstwa [métier]
session_start();
if (!isset($_SESSION['metier'])) {
// instancja warstwy [dao] oraz warstwy [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'];

// pobieramy wiersz wysłany przez klienta
$params = utf8_encode(htmlspecialchars(strtolower(trim($_POST['params']))));
//print "otrzymane parametry --> $params\n";
$items = explode(",", $params);
// powinny być tylko 3 parametry
if (count($items) != 3) {
  print "<reponse><erreur>[$params] : nombre de paramètres invalides</erreur></reponse>\n";
  exit;
}//if
// pierwszy parametr (stan cywilny) musi mieć wartość „tak” lub „nie”
$marié = trim($items[0]);
if ($marié != "oui" and $marié != "non") {
  print "<reponse><erreur>[$params] : 1er paramètre invalide</erreur></reponse>\n";
  exit;
}//if
// drugi parametr (liczba dzieci) musi być liczbą całkowitą
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];
// trzeci parametr (wynagrodzenie) musi być liczbą całkowitą
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];
// obliczamy podatek
$impôt = $metier->calculerImpot($marié, $enfants, $salaire);
// zwracamy wynik
print "<reponse><impot>$impôt</impot></reponse>\n";
// koniec
exit;

Format odpowiedzi serwisu internetowego został zmieniony w wierszach 35, 47, 53, 58, 64 i 71.

13.2. Klient (client_impots_05b_web)

Klient został zmodyfikowany w celu uwzględnienia nowego formatu odpowiedzi. Do przetworzenia tej odpowiedzi używamy identyfikatora [simpleXML]:


<?php

// klient podatkowy
// obsługa błędów
ini_set("display_errors", "off");

// ---------------------------------------------------------------------------------
// klasa funkcji pomocniczych
class Utilitaires {
...
}

// main -----------------------------------------------------
// definicja stałych
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
// dane serwera
$HOTE = "localhost";
$PORT = 80;
$urlServeur = "/exemples-web/impots_05B_web.php";

...
exit;

function calculerImpot($HOTE, $PORT, $urlServeur, &$cookie, $params) {
  // łączy klienta z ($HOTE,$PORT,$urlServeur)
// wysyła plik cookie $cookie, jeśli nie jest on pusty. $cookie jest przekazywany przez odwołanie
// wysyła plik cookie o nazwie $params do serwera
// przetwarza wiersz wyniku
...
  // odczytuje wiersz wyniku
  $ligne = fgets($connexion, 1000);
  // zamyka się połączenie
  fclose($connexion);
  // oblicza wynik
  $xml = new SimpleXMLElement($ligne);
  $erreur = isset($xml->erreur) ? $xml->erreur : "";
  $impôt = isset($xml->impot) ? $xml->impot : "";
  // powrót
  return array($erreur, $impôt);
}
  • wiersz 32: odczytano odpowiedź serwera. Jest to dokument XML.
  • wiersz 36: na podstawie otrzymanego dokumentu XML tworzony jest obiekt SimpleXML.
  • wiersz 37: ewentualny komunikat o błędzie
  • wiersz 38: ewentualna kwota podatku