Skip to content

6. Exercice d'application - IMPOTS avec objets (impots_03)

On reprend l'exercice déjà étudié précédemment (paragraphes 4.2 et 4.3) pour le résoudre avec un code PHP utilisant une classe.


<?php

// définition d'une classe Impôts
class Impôts {

  // attributs : les 3 tableaux de données
  private $limites;
  private $coeffR;
  private $coeffN;
  
  // constructeur

  public function __construct($IMPOTS) {
    // $IMPOTS : le nom du fichier contenant les données des tables $limites, $coeffR, $coeffN
    // le fichier $IMPOTS existe-t-il ?
    if (!file_exists($IMPOTS)) {
      throw new Exception("Le fichier $IMPOTS n'existe pas");
    }//if
    // lecture en bloc du fichier
    $tables = file($IMPOTS);
    if (!$tables) {
      throw new Exception("Erreur lors de l'exploitation du fichier $IMPOTS");
    }//if
    // création des 3 tables - on suppose que les lignes sont syntaxiquement correctes
    $u = new Utilitaires(); // pour disposer de fonctions utilitaires
    $this->limites = explode(":", $u->cutNewLineChar($tables[0]));
    $this->coeffR = explode(":", $u->cutNewLineChar($tables[1]));
    $this->coeffN = explode(":", $u->cutNewLineChar($tables[2]));
    }

  // --------------------------------------------------------------------------
  public function calculer($marié, $enfants, $salaire) {
    // $marié : oui, non
    // $enfants : nombre d'enfants
    // $salaire : salaire annuel
    
    // nombre de parts
    $marié = strtolower($marié);
    if ($marié == "oui")
      $nbParts = $enfants / 2 + 2;
    else
      $nbParts=$enfants / 2 + 1;
    // une 1/2 part de plus si au moins 3 enfants
    if ($enfants >= 3)
      $nbParts+=0.5;
    // revenu imposable
    $revenuImposable = 0.72 * $salaire;
    // quotient familial
    $quotient = $revenuImposable / $nbParts;
    // est mis à la fin du tableau limites pour arrêter la boucle qui suit
    $this->limites[count($this->limites) - 1] = $quotient;
    // calcul de l'impôt
    $i = 0;
    while ($quotient > $this->limites[$i])
      $i++;
    // du fait qu'on a placé $quotient à la fin du tableau $limites, la boucle précédente
    // ne peut déborder du tableau $limites
    // maintenant on peut calculer l'impôt
    return floor($revenuImposable * $this->coeffR[$i] - $nbParts * $this->coeffN[$i]);
  }

}

// une classe de fonctions utilitaires
class Utilitaires {

  public function cutNewLinechar($ligne) {
    // on supprime la marque de fin de ligne de $ligne si elle existe
    $L = strlen($ligne);  // longueur ligne
    while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
      $ligne = substr($ligne, 0, $L - 1);
      $L--;
    }//while
    // fin
    return($ligne);
  }

}

// test -----------------------------------------------------
// définition des constantes
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
$IMPOTS = "impots.txt";
// les données nécessaires au calcul de l'impôt ont été placées dans le fichier IMPOTS
// à raison d'une ligne par tableau sous la forme
// "val1":"val2":"val3",...
// on crée un objet Impôts
try {
  $I = new Impôts($IMPOTS);
} catch (Exception $e) {
  print $e->getMessage();
  exit;
}
// on crée un objet utilitaires
$u = new Utilitaires();

// lecture des données utilisateur
$data = fopen($DATA, "r");
if (!$data) {
  print "Impossible d'ouvrir en lecture le fichier des données [$DATA]\n";
  exit;
}

// ouverture fichier des résultats
$résultats = fopen($RESULTATS, "w");
if (!$résultats) {
  print "Impossible de créer le fichier des résultats [$RESULTATS]\n";
  exit;
}

// on exploite la ligne courante du fichier des données
while ($ligne = fgets($data, 100)) {
  // on enlève l'éventuelle marque de fin de ligne
  $ligne = $u->cutNewLineChar($ligne);
  // on récupère les 3 champs marié,enfants,salaire qui forment $ligne
  list($marié, $enfants, $salaire) = explode(",", $ligne);
  // on calcule l'impôt
  $impôt = $I->calculer($marié, $enfants, $salaire);
  // on inscrit le résultat
  fputs($résultats, "$marié:$enfants:$salaire:$impôt\n");
  // donnée suivante
}// while
// on ferme les fichiers
fclose($data);
fclose($résultats);

// fin
print "Terminé\n";
exit;
?>

Le fichier [impots.txt] :

12620:13190:15640:24740:31810:39970:48360:55790:92970:127860:151250:172040:195000:0
0:0.05:0.1:0.15:0.2:0.25:0.3:0.35:0.4:0.45:0.5:0.55:0.6:0.65
0:631:1290.5:2072.5:3309.5:4900:6898.5:9316.5:12106:16754.5:23147.5:30710:39312:49062

Le fichier [data.txt]

oui,2,200000
non,2,200000
oui,3,200000
non,3,200000
oui,5,50000
non,0,3000000

Résultats : ceux déjà obtenus dans les versions avec tableaux et fichiers.

Le fichier [resultats.txt]

oui:2:200000:22504
non:2:200000:33388
oui:3:200000:16400
non:3:200000:22504
oui:5:50000:0
non:0:3000000:1354938

Commentaires

  • ligne 4 : la classe Impôts. Elle encapsule des données et des méthodes permettant le calcul de l'impôt :
  • données : lignes 7-9 – ce sont les trois tableaux de données permettant le calcul de l'impôt. Ces trois tableaux sont initialisés par le constructeur de la ligne 13 à partir d'un fichier texte.
  • méthodes : ligne 32 – la méthode calculer permet de calculer l'impôt.
  • lignes 17, 22 : lorsque le constructeur ne peut pas construire l'objet Impôts, il lance une exception.
  • ligne 25 : la classe Utilitaires a été définie pour encapsuler la fonction cutNewLineChar.
  • lignes 26-28 : initialisation des trois champs privés de la classe Impôts
  • ligne 32 : la méthode calculer de la classe Impôts permet de calculer l'impôt d'un contribuable.
  • lignes 65-78 : la classe Utilitaires
  • lignes 89-94 : construction d'un objet Impôts avec gestion de l'exception éventuelle. Cette construction va exploiter le fichier texte $IMPOTS pour mettre son contenu dans les trois champs privés de l'objet Impôts.
  • lignes 96 : construction d'un objet Utilitaires pour disposer de la fonction cutNewLineChar.