Skip to content

6. Exercício prático — IMPOTS com objetos (impots_03)

Retomamos o exercício já estudado anteriormente (parágrafos 4.2 e 4.3) para o resolver com um código PHP utilizando uma classe.


<?php

// definição de uma classe Impostos
class Impôts {

  // atributos: as 3 tabelas de dados
  private $limites;
  private $coeffR;
  private $coeffN;
  
  // construtor

  public function __construct($IMPOTS) {
    // $IMPOTS: o nome do ficheiro que contém os dados das tabelas $limites, $coeffR, $coeffN
    // O ficheiro $IMPOTS existe?
    if (!file_exists($IMPOTS)) {
      throw new Exception("Le fichier $IMPOTS n'existe pas");
    }//se
    // leitura em bloco do ficheiro
    $tables = file($IMPOTS);
    if (!$tables) {
      throw new Exception("Erreur lors de l'exploitation du fichier $IMPOTS");
    }//se
    // criação das 3 tabelas — parte-se do princípio de que as linhas estão sintaticamente corretas
    $u = new Utilitaires(); // para dispor de funções utilitárias
    $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é: sim, não
    // $enfants: número de filhos
    // $salaire: salário anual
    
    // número de quotas
    $marié = strtolower($marié);
    if ($marié == "oui")
      $nbParts = $enfants / 2 + 2;
    else
      $nbParts=$enfants / 2 + 1;
    // mais meia quota se houver pelo menos 3 filhos
    if ($enfants >= 3)
      $nbParts+=0.5;
    // rendimento tributável
    $revenuImposable = 0.72 * $salaire;
    // quociente familiar
    $quotient = $revenuImposable / $nbParts;
    // é colocado no final da tabela de limites para interromper o ciclo seguinte
    $this->limites[count($this->limites) - 1] = $quotient;
    // cálculo do imposto
    $i = 0;
    while ($quotient > $this->limites[$i])
      $i++;
    // uma vez que se colocou $quotient no final da tabela $limites, o ciclo anterior
    // não pode ultrapassar os limites da tabela $limites
    //; agora é possível calcular o imposto
    return floor($revenuImposable * $this->coeffR[$i] - $nbParts * $this->coeffN[$i]);
  }

}

// uma classe de funções utilitárias
class Utilitaires {

  public function cutNewLinechar($ligne) {
    // eliminamos o marcador de fim de linha de $ligne, caso exista
    $L = strlen($ligne);  // comprimento da linha
    while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
      $ligne = substr($ligne, 0, $L - 1);
      $L--;
    }//enquanto
    // fim
    return($ligne);
  }

}

// teste -----------------------------------------------------
// definição das constantes
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
$IMPOTS = "impots.txt";
// os dados necessários para o cálculo do imposto foram colocados no ficheiro IMPOTS
// à razão de uma linha por tabela, na forma
// "val1":"val2":"val3",...
// cria-se um objeto Impostos
try {
  $I = new Impôts($IMPOTS);
} catch (Exception $e) {
  print $e->getMessage();
  exit;
}
// cria-se um objeto utilitários
$u = new Utilitaires();

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

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

// processa-se a linha atual do ficheiro de dados
while ($ligne = fgets($data, 100)) {
  // remove-se o eventual caractere de fim de linha
  $ligne = $u->cutNewLineChar($ligne);
  // recuperam-se os 3 campos «casado», «filhos» e «salário» que formam $ligne
  list($marié, $enfants, $salaire) = explode(",", $ligne);
  // calcula-se o imposto
  $impôt = $I->calculer($marié, $enfants, $salaire);
  // regista-se o resultado
  fputs($résultats, "$marié:$enfants:$salaire:$impôt\n");
  // dado seguinte
}// enquanto
// fecha-se os ficheiros
fclose($data);
fclose($résultats);

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

O ficheiro [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

O ficheiro [data.txt]

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

Resultados: os já obtidos nas versões com tabelas e ficheiros.

O ficheiro [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

Comentários

  • linha 4: a classe Impostos. Esta encapsula dados e métodos que permitem o cálculo do imposto:
  • dados: linhas 7-9 – são as três tabelas de dados que permitem o cálculo do imposto. Estas três tabelas são inicializadas pelo construtor da linha 13 a partir de um ficheiro de texto.
  • métodos: linha 32 – o método calculer permite calcular o imposto.
  • linhas 17, 22: quando o construtor não consegue criar o objeto Impôts, lança uma exceção.
  • linha 25: a classe Utilitaires foi definida para encapsular a função cutNewLineChar.
  • linhas 26-28: inicialização dos três campos privados da classe Impôts
  • linha 32: o método calculer da classe Impôts permite calcular o imposto de um contribuinte.
  • linhas 65-78: a classe Utilitaires
  • linhas 89-94: criação de um objeto Impôts com gestão de eventuais exceções. Esta criação irá utilizar o ficheiro de texto $IMPOTS para inserir o seu conteúdo nos três campos privados do objeto Impôts.
  • linhas 96: criação de um objeto Utilitaires para poder utilizar a função cutNewLineChar.