8. IMPOTS alıştırması ile MySQL
Bu alıştırmanın üç versiyonunu daha önce yazmıştık. Son versiyonda bir vergi hesaplama sınıfı kullanılmıştı. Bu sınıf, hesaplamayı yapmak için gerekli verileri bir metin dosyasından alıyordu. Artık bu verileri bir veritabanından alacak. Bunun için, metin dosyasındaki verileri bir veritabanına aktaracak ilk kodu yazıyoruz.
impots.txt metin dosyası şu şekildedir:
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
Oluşturulacak veritabanı şöyledir:
![]() | ![]() |
Veritabanının adı [dbimpots]'tir ve tek bir tablo içerir: [impots]. Bu veritabanı, [root] kullanıcı adı ile şifre gerektirmeden kullanılmaktadır.
8.1. Bir metin dosyasının MySQL tablosuna aktarılması (txt2mysql)
<?php
// vergilerin hesaplanması için gerekli verilerin bulunduğu metin dosyasını aktarır
// bir MySQL tablosuna aktarılır
// veriler
$IMPOTS = "impots.txt";
$BASE = "dbimpots";
$TABLE = "impots";
$USER = "root";
$PWD = "";
$HOTE = "localhost";
// vergi hesaplaması için gerekli veriler $IMPOTS dosyasına yerleştirildi
// dosyasına, her tablo için bir satır olacak şekilde şu biçimde yerleştirilmiştir
// val1:val2:val3,...
list($erreur, $limites, $coeffR, $coeffN) = getTables($IMPOTS);
// Bir hata mı oluştu?
if ($erreur) {
print "$erreur\n";
exit;
}//if
// bu tabloları bir MySQL tablosuna aktarıyoruz
$erreur = copyToMysql($limites, $coeffR, $coeffN, $HOTE, $USER, $PWD, $BASE, $TABLE);
if ($erreur)
print "$erreur\n";
else
print "Transfert opéré\n";
// son
exit;
// --------------------------------------------------------------------------
function copyToMysql($limites, $coeffR, $coeffN, $HOTE, $USER, $PWD, $BASE, $TABLE) {
// $limites, $coeffR, $coeffN adlı 3 sayısal tabloyu
// $BASE adlı MySQL veritabanındaki $TABLE tablosuna
// mysql veritabanı $HOTE makinesinde bulunuyor
// kullanıcı, $USER ve $PWD ile tanımlanmıştır
// bağlantı
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";
// tablonun silinmesi
$requête = "drop table $TABLE";
exécuteRequête($connexion, $requête);
// tablo oluşturma
$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)";
// doldurma
for ($i = 0; $i < count($limites); $i++) {
// ekleme sorgusu
$requête = "insert into $TABLE (limites,coeffR,coeffN) values ($limites[$i],$coeffR[$i],$coeffN[$i])";
// sorgunun yürütülmesi
list($erreur, $res) = exécuteRequête($connexion, $requête);
// hata durumunda geri dönüş
if ($erreur)
return "$requête : erreur ($erreur)";
}//for
// işlem tamamlandı - bağlantı kesiliyor
déconnecte($connexion);
// hata olmadan geri dönüş
return "";
}
// --------------------------------------------------------------------------
function getTables($IMPOTS) {
// $IMPOTS : $limites, $coeffR, $coeffN tablolarının verilerini içeren dosyanın adı
...
// son
return array("", $limites, $coeffR, $coeffN);
}
// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
// varsa, $ligne dosyasındaki satır sonu işaretini silin
...
// son
return($ligne);
}
// ---------------------------------------------------------------------------------
function connecte($dsn, $login, $pwd) {
// ($login,$pwd) veritabanına $dsn ile bağlanır
// bağlantı kimliğini ve bir hata mesajını döndürür
...
}
//bağlantı kurar
// ---------------------------------------------------------------------------------
function déconnecte($connexion) {
//, $connexion ile tanımlanan bağlantıyı kapatır
...
}
// ---------------------------------------------------------------------------------
function exécuteRequête($connexion, $sql) {
//, $sql sorgusunu $connexion bağlantısı üzerinden yürütür
// 2 elemanlı bir dizi döndürür ($erreur,$résultat)
...
}
Ekran çıktısı:
8.2. Vergi hesaplama programı ( impots_04)
Bu sürüm, vergi hesaplaması için gerekli değerleri veritabanından alan Impôts sınıfını kullanır. Burada, hazır sorgu kavramını tanıtıyoruz. Bir SQL emrinin bir SGBD tarafından yürütülmesi iki aşamada gerçekleşir:
- sorgu hazırlanır: SGBD, sorgu için optimize edilmiş bir yürütme planı hazırlar. Amaç, sorguyu mümkün olduğunca verimli bir şekilde yürütmektir.
- Sorgu yürütülür.
Aynı sorgu N kez yürütülürse, yukarıdaki iki adım da N kez gerçekleştirilir. Ancak, sorguyu 1 kez hazırlayıp N kez yürütmek de mümkündür. Bunun için hazırlanmış sorgular kullanılmalıdır. $requête, yürütülmesi gereken SQL komutuysa ve $connexion, bağlantıyı temsil eden PDO nesnesi ise:
- $statement=$connexion->prepare($requête) bir sorgu hazırlar ve sorguyu "hazırlanmış" hale getirir
- $statement->execute(), hazırlanan sorguyu yürütür.
Hazırlanan sorgu bir select komutuysa, o zaman
- $statement->fetchAll() komutu, select tablosunun sonuç satırlarının tümünü bir T dizisi biçiminde döndürür; burada T[i,j], i satırının j sütunundaki değerdir
- $statement->fetch(), tablonun geçerli satırını bir T dizisi biçiminde döndürür; burada T[j], satırın j sütunundaki değerdir
Hazırlanan sorgu, daha yüksek verimlilik dışında başka avantajlar da sağlar. Özellikle daha fazla güvenlik sağlar. Bu nedenle, bu yöntem sistematik olarak kullanılmalıdır.
<?php
// test -----------------------------------------------------
// sabitlerin tanımlanması
$DATA = "data.txt";
$RESULTATS = "resultats.txt";
$TABLE = "impots";
$BASE = "dbimpots";
$USER = "root";
$PWD = "";
$HOTE="localhost";
// vergi hesaplaması için gerekli veriler mysqL $TABLE tablosuna yerleştirilmiştir
// tablosu, $BASE veritabanına aittir. Tablonun yapısı şöyledir
// sınırlar decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
// vergiye tabi kişilerin parametreleri (medeni durum, çocuk sayısı, yıllık maaş)
// vergi mükellefi başına bir satır olacak şekilde $DATA metin dosyasına yerleştirilmiştir
// sonuçlar (medeni durum, çocuk sayısı, yıllık maaş, ödenecek vergi)
// her satıra bir sonuç olacak şekilde $RESULTATS metin dosyasına yerleştirilmiştir
// bir Vergi nesnesi oluşturulur
$I = new Impôts($HOTE, $USER, $PWD, $BASE, $TABLE);
// bir hata mı oluştu?
$erreur=$I->getErreur();
if ($erreur) {
print "$I->erreur\n";
exit;
}//if
// bir yardımcı nesne oluşturulur
$u = new Utilitaires();
// mükellef verileri dosyasının açılması
$data = fopen($DATA, "r");
if (!$data) {
print "Impossible d'ouvrir en lecture le fichier des données [$DATA]\n";
exit;
}
// sonuç dosyasının açılması
$résultats = fopen($RESULTATS, "w");
if (!$résultats) {
print "Impossible de créer le fichier des résultats [$RESULTATS]\n";
exit;
}
// vergi mükellefi verileri dosyasının geçerli satırı işleniyor
while ($ligne = fgets($data, 100)) {
// varsa satır sonu işaretini kaldırıyoruz
$ligne = $u->cutNewLineChar($ligne);
// $ligne'i oluşturan "evli", "çocuk sayısı" ve "maaş" olmak üzere 3 alanı alınır
list($marié, $enfants, $salaire) = explode(",", $ligne);
// vergi hesaplanıyor
$impôt = $I->calculer($marié, $enfants, $salaire);
// sonuç yazılır
fputs($résultats, "$marié:$enfants:$salaire:$impôt\n");
// sonraki veriye geçilir
}
// dosyalar kapatılır
fclose($data);
fclose($résultats);
// son
exit;
// ---------------------------------------------------------------------------------
// "Vergiler" sınıfının tanımlanması
class Impôts {
// özellikler: 3 veri tablosu
private $limites;
private $coeffR;
private $coeffN;
private $erreur;
private $nbLimites;
// getter
public function getErreur(){
return $this->erreur;
}
// oluşturucu
function __construct($HOTE, $USER, $PWD, $BASE, $TABLE) {
// $limites, $coeffR, $coeffN özniteliklerini başlatır
// vergi hesaplaması için gerekli veriler, $TABLE adlı MySQL tablosuna yerleştirilmiştir
// tabloya eklenmiştir. Bu tablo, $BASE veritabanına aittir. Tablonun yapısı aşağıdaki gibidir
// sınırlar decimal(10,2), coeffR decimal(6,2), coeffN decimal(10,2)
// $HOTE makinesinin MySQL veritabanına bağlantı, ($USER,$PWD) kimlik bilgileriyle yapılır
// $erreur alanını olası bir hata ile başlatır
// hata yoksa boş bırakılır
//
// MySQL veritabanına bağlanır
$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;
}
// $TABLE tablosunu okur
$requête = "select limites,coeffR,coeffN from $TABLE";
// $requête sorgusunu $connexion bağlantısı üzerinden yürütür
try {
$statement = $connexion->prepare($requête);
$statement->execute();
// sorgu sonucunun işlenmesi
while ($colonnes = $statement->fetch()) {
$this->limites[] = $colonnes[0];
$this->coeffR[] = $colonnes[1];
$this->coeffN[] = $colonnes[2];
}
// hata yok
$this->erreur = "";
// dizideki öğe sayısı sınırın içinde
$this->nbLimites = count($this->limites);
} catch (PDOException $e) {
$this->erreur = $e->getMessage();
}
// bağlantı kesildi
déconnecte($connexion);
}
// --------------------------------------------------------------------------
function calculer($marié, $enfants, $salaire) {
// $marié: evet, hayır
// $enfants: çocuk sayısı
// $salaire : yıllık maaş
// nesne düzgün durumda mı?
if ($this->erreur)
return -1;
// pay sayısı
...
}
}
// ---------------------------------------------------------------------------------
// bir yardımcı işlev sınıfı
class Utilitaires {
function cutNewLinechar($ligne) {
// varsa, $ligne'ten satır sonu işaretini silin
...
}
}
// ---------------------------------------------------------------------------------
function connecte($dsn, $login, $pwd) {
// ($login, $pwd) veritabanına $dsn'e bağlanır
//, bağlantı kimliğini ve bir hata mesajını döndürür
...
}
//bağlantı kurar
// ---------------------------------------------------------------------------------
function déconnecte($connexion) {
//, $connexion ile tanımlanan bağlantıyı kapatır
...
}
Sonuçlar: önceki sürümlerle aynıdır.
Yorumlar
Yenilikler 98-109. satırlarda yer almaktadır:
- 99. satır: Vergi hesaplaması için gerekli verilerin alınmasını sağlayacak olan SQL select emri.
- 102. satır: SQL select komutunun hazırlanması
- satır 103: Hazırlanan komutun yürütülmesi
- satır 105-109: select komutunun sonuç tablosunun satır satır işlenmesi

