8. تمرين حساب الضرائب باستخدام MySQL
لقد كتبنا بالفعل ثلاث نسخ من هذا التمرين. استخدمت أحدث نسخة فئة لحساب الضرائب. استردت هذه الفئة البيانات اللازمة للحساب من ملف نصي. وستستردها الآن من قاعدة بيانات. للقيام بذلك، نكتب كودًا أوليًا ينقل البيانات من الملف النصي إلى قاعدة البيانات.
الملف النصي 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:272.5:3309.5:4900:6898.5:9316.5:12106:16754.5:23147.5:30710:39312:49062
قاعدة البيانات المراد إنشاؤها هي كما يلي:
![]() | ![]() |
تسمى قاعدة البيانات [dbimpots] وتحتوي على جدول واحد [impots]. يتم الوصول إليها بواسطة المستخدم [root] بدون كلمة مرور.
8.1. استيراد ملف نصي إلى جدول MySQL (txt2mysql)
<?php
// transfers the text file containing the data needed to calculate taxes
// in a mysql table
// the data
$IMPOTS = "impots.txt";
$BASE = "dbimpots";
$TABLE = "impots";
$USER = "root";
$PWD = "";
$HOTE = "localhost";
// the data required to calculate the tax has been placed in the $IMPOTS file
// one line per table in the form
// val1:val2:val3,...
list($erreur, $limites, $coeffR, $coeffN) = getTables($IMPOTS);
// was there a mistake?
if ($erreur) {
print "$erreur\n";
exit;
}//if
// transfer these tables to a mysql table
$erreur = copyToMysql($limites, $coeffR, $coeffN, $HOTE, $USER, $PWD, $BASE, $TABLE);
if ($erreur)
print "$erreur\n";
else
print "Transfert opéré\n";
// end
exit;
// --------------------------------------------------------------------------
function copyToMysql($limites, $coeffR, $coeffN, $HOTE, $USER, $PWD, $BASE, $TABLE) {
// copy the 3 numerical tables $limites, $coeffR, $coeffN
// in table $TABLE of mysql database $BASE
// the mysql database is on machine $HOTE
// the user is identified by $USER and $PWD
// connection
list($erreur, $connexion) = connecte("mysql:host=$HOTE;dbname=$BASE", $USER, $PWD);
if ($erreur)
return "Erreur lors de la connexion à MySql sous l'identité ($HOTE,$USER,$PWD) : $erreur\n";
// table deletion
$requête = "drop table $TABLE";
exécuteRequête($connexion, $requête);
// table creation
$requête = "create table $TABLE (limites decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2))";
list($erreur, $res) = exécuteRequête($connexion, $requête);
if ($erreur)
return "$requête : erreur ($erreur)";
// filling
for ($i = 0; $i < count($limites); $i++) {
// insertion request
$requête = "insert into $TABLE (limites,coeffR,coeffN) values ($limites[$i],$coeffR[$i],$coeffN[$i])";
// query execution
list($erreur, $res) = exécuteRequête($connexion, $requête);
// return if error
if ($erreur)
return "$requête : erreur ($erreur)";
}//for
// it's over - log off
déconnecte($connexion);
// error-free return
return "";
}
// --------------------------------------------------------------------------
function getTables($IMPOTS) {
// $IMPOTS: name of the file containing data from tables $limites, $coeffR, $coeffN
...
// end
return array("", $limites, $coeffR, $coeffN);
}
// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
// delete the end-of-line mark from $ligne if it exists
...
// end
return($ligne);
}
// ---------------------------------------------------------------------------------
function connecte($dsn, $login, $pwd) {
// connects ($login,$pwd) to base $dsn
// returns the connection id and an error msg
...
}
//connect
// ---------------------------------------------------------------------------------
function déconnecte($connexion) {
// closes the connection identified by $connexion
...
}
// ---------------------------------------------------------------------------------
function exécuteRequête($connexion, $sql) {
// executes the $sql request on the $connexion connection
// returns an array of 2 elements ($erreur,$résultat)
...
}
نتائج الشاشة:
8.2. برنامج حساب الضرائب ( impots_04)
تستخدم هذه النسخة فئة Impôts التي تسترد القيم اللازمة لحساب الضريبة من قاعدة البيانات. نقدم هنا مفهومًا جديدًا: العبارة المعدة مسبقًا. يتم تنفيذ عبارة SQL بواسطة نظام إدارة قواعد البيانات (DBMS) على مرحلتين:
- يتم إعداد الاستعلام: يقوم نظام إدارة قواعد البيانات (DBMS) بإعداد خطة تنفيذ محسّنة للاستعلام. والهدف هو تنفيذه بأكبر قدر ممكن من الكفاءة.
- تنفيذ الاستعلام.
إذا تم تنفيذ نفس الاستعلام N مرات، يتم تنفيذ الخطوتين السابقتين N مرات. ومع ذلك، من الممكن إعداد الاستعلام مرة واحدة وتنفيذه N مرات. للقيام بذلك، يجب استخدام الاستعلامات المعدة مسبقًا. إذا كان $query هو عبارة SQL المراد تنفيذها و$connection هو كائن PDO الذي يمثل الاتصال:
- $statement = $connection->prepare($query) يقوم بإعداد استعلام وإرجاع الاستعلام "المُعد"
- $statement->execute() ينفذ الاستعلام المُعد.
إذا كان الاستعلام المُعد عبارة عن عبارة SELECT، فإن
- $statement->fetchAll() تُرجع جميع الصفوف من جدول نتائج استعلام SELECT كمصفوفة T، حيث T[i,j] هي قيمة العمود j في الصف i من الجدول
- تُرجع الدالة $statement->fetch() الصف الحالي من الجدول على شكل مصفوفة T، حيث تمثل T[j] قيمة العمود j في الصف
تقدم العبارات المعدة مسبقًا مزايا تتجاوز مجرد تحسين الكفاءة. وعلى وجه الخصوص، توفر أمانًا أكبر. ولذلك، ينبغي استخدامها بشكل منهجي.
<?php
// test -----------------------------------------------------
// definition of constants
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
$TABLE = "impots";
$BASE = "dbimpots";
$USER = "root";
$PWD = "";
$HOTE="localhost";
// 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)
// were placed in the $DATA text file, one line for each taxpayer
// the results (marital status, number of children, annual salary, tax payable) are placed in the
// the $RESULTATS text file, with one result per line
// create a Tax object
$I = new Impôts($HOTE, $USER, $PWD, $BASE, $TABLE);
// was there a mistake?
$erreur=$I->getErreur();
if ($erreur) {
print "$I->erreur\n";
exit;
}//if
// create a utilities object
$u = new Utilitaires();
// opening taxpayer data files
$data = fopen($DATA, "r");
if (!$data) {
print "Impossible d'ouvrir en lecture le fichier des données [$DATA]\n";
exit;
}
// open results file
$résultats = fopen($RESULTATS, "w");
if (!$résultats) {
print "Impossible de créer le fichier des résultats [$RESULTATS]\n";
exit;
}
// the current line of the taxpayer data file is used
while ($ligne = fgets($data, 100)) {
// remove any end-of-line marker
$ligne = $u->cutNewLineChar($ligne);
// we retrieve the 3 fields married,children,salary which form $ligne
list($marié, $enfants, $salaire) = explode(",", $ligne);
// tax calculation
$impôt = $I->calculer($marié, $enfants, $salaire);
// enter the result
fputs($résultats, "$marié:$enfants:$salaire:$impôt\n");
// following data
}
// close files
fclose($data);
fclose($résultats);
// end
exit;
// ---------------------------------------------------------------------------------
// definition of a Tax class
class Impôts {
// attributes: the 3 data tables
private $limites;
private $coeffR;
private $coeffN;
private $erreur;
private $nbLimites;
// getter
public function getErreur(){
return $this->erreur;
}
// manufacturer
function __construct($HOTE, $USER, $PWD, $BASE, $TABLE) {
// initializes $limites, $coeffR, $coeffN attributes
// the data required 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)
// connection to the mysql database on machine $HOTE is made as ($USER,$PWD)
// initializes the $erreur field with a possible error
// empty if no error
//
// connection to mysql database
$DSN = "mysql:host=$HOTE;dbname=$BASE";
list($erreur, $connexion) = connecte($DSN, $USER, $PWD);
if ($erreur) {
$this->erreur = "Erreur lors de la connexion à MySql sous l'identité ($HOTE,$USER,$PWD) : $erreur\n";
return;
}
// read table $TABLE
$requête = "select limites,coeffR,coeffN from $TABLE";
// executes the $requête request on the $connexion connection
try {
$statement = $connexion->prepare($requête);
$statement->execute();
// query result evaluation
while ($colonnes = $statement->fetch()) {
$this->limites[] = $colonnes[0];
$this->coeffR[] = $colonnes[1];
$this->coeffN[] = $colonnes[2];
}
// no error
$this->erreur = "";
// number of elements in the limit table
$this->nbLimites = count($this->limites);
} catch (PDOException $e) {
$this->erreur = $e->getMessage();
}
// disconnect
déconnecte($connexion);
}
// --------------------------------------------------------------------------
function calculer($marié, $enfants, $salaire) {
// $marié : yes, no
// $enfants : number of children
// $salaire: annual salary
// is the item in good condition?
if ($this->erreur)
return -1;
// number of shares
...
}
}
// ---------------------------------------------------------------------------------
// a class of utility functions
class Utilitaires {
function cutNewLinechar($ligne) {
// delete the end-of-line mark from $ligne if it exists
...
}
}
// ---------------------------------------------------------------------------------
function connecte($dsn, $login, $pwd) {
// connects ($login,$pwd) to base $dsn
// returns the connection id and an error msg
...
}
//connect
// ---------------------------------------------------------------------------------
function déconnecte($connexion) {
// closes the connection identified by $connexion
...
}
النتائج: نفس النتائج مع الإصدارات السابقة.
تعليقات
الميزات الجديدة موجودة في الأسطر 98–109:
- السطر 99: عبارة SQL SELECT التي تسترد البيانات اللازمة لحساب الضريبة.
- السطر 102: إعداد عبارة SQL SELECT
- السطر 103: تنفيذ الجملة المعدة
- الأسطر 105-109: معالجة جدول نتائج جملة SELECT سطراً سطراً

