10 Mart 2015 Salı

PDO ile MySQL Veritabanı İşlemleri Yapan Class


Bugün, PHP'de PDO ile MySQL veritabanı işlemleri yapmamıza olanak sağlayan bir class'ımı tanıtmak ve kullanımınıza sunmak istiyorum.

Amacımız kodlama yaparken hız kazanmak mı? O halde kendi hazır fonksiyonlarımız, class'larımız olmalı. Şimdi bu bağlamda, PHP'de PDO kullanarak MySQL bağlantısı sağlayan ve temel veritabanı işlemleri olan SELECT, INSERT, UPDATE ve DELETE işlemlerini yapabilen bir class yapısını sizlerle paylaşacağım.

class ebykdrms_Veritabani {
 
    private $db;
    private $dsn;
    private $user;
    private $password;

    function __construct() {      
        $this->dsn = 'mysql:host=localhost;dbname=veritabaniadi;charset=utf8';
        $this->user = 'root';
        $this->password = '1234';
    }

    private function baglantiAc() {
        try { $this->db = new PDO($this->dsn, $this->user, $this->password); }
        catch (PDOException $e) { echo 'Veritabanı bağlantısı başarısız oldu: ' . $e->getMessage(); }
    }

    private function baglantiKapat() {
        $this->db = null;
    }

    function ekle($tablo, $veriler) {
        $sonuc = 0;
        $alan1 = "";
        $alan2 = "";
        foreach ($veriler as $anahtar => $deger) {
            $alan1 .= $anahtar . ",";
            $alan2 .= ":".$anahtar.",";
        }
        $alan1 = substr($alan1,0,strlen($alan1)-1);
        $alan2 = substr($alan2,0,strlen($alan2)-1);
        $this->baglantiAc();
        $query = $this->db->prepare("INSERT INTO ".$tablo." (".$alan1.") VALUES (".$alan2.")");
        $query->execute($veriler);
        if ( $query ) $sonuc = $this->db->lastInsertId(); else $sonuc = 0;
        $this->baglantiKapat();
        return $sonuc;
    }

    function guncelle($tablo, $veriler, $where="") {
        $sonuc = "";
        $alan = "";
        foreach ($veriler as $anahtar => $deger) $alan .= $anahtar . "= :".$anahtar.",";
        $alan = substr($alan,0,strlen($alan)-1);
        if($where!="") $where = " WHERE ".$where;
        $this->baglantiAc();
        $query = $this->db->prepare("UPDATE ".$tablo." SET ".$alan.$where);
        $update = $query->execute($veriler);
        if ( $update ) $sonuc = $query->rowCount(); else $sonuc = 0;
        $this->baglantiKapat();
        return $sonuc;
    }

    function idGuncelle($tablo, $veriler, $id) {
        $sonuc = 0;
        $alan = "";
        foreach ($veriler as $anahtar => $deger) $alan .= $anahtar . "= :".$anahtar.",";
        $alan = substr($alan,0,strlen($alan)-1);
        $veriler['id'] = (int)$id;
        $this->baglantiAc();
        $query = $this->db->prepare("UPDATE ".$tablo." SET ".$alan." WHERE id=:id");
        $update = $query->execute($veriler);
        if ( $update ) $sonuc = 1; else $sonuc = 0;
        $this->baglantiKapat();
        return $sonuc;
    }

    function sil($tablo,$where) {
    $this->baglantiAc();      
        $delete = $this->db->exec("DELETE FROM ".$tablo." WHERE ".$where);
        $this->baglantiKapat();
        return $delete;
    }

    function idSil($tablo,$id) {
        $sonuc = 0;
    $this->baglantiAc();
        $query = $this->db->prepare("DELETE FROM ".$tablo." WHERE id = :id");
        $delete = $query->execute(array('id' => (int)$id));
        if ( $delete ) $sonuc = 1; else $sonuc = 0;
        $this->baglantiKapat();
        return $sonuc;
    }

    function select($tablo,$diger="") {
        $sonuc = null;
        $this->baglantiAc();
        $query = $this->db->query("SELECT * FROM ".$tablo." ".$diger, PDO::FETCH_ASSOC);
        if ( $query ) $sonuc = $query; else $sonuc = null;
        $this->baglantiKapat();
        return $sonuc;
    }
}

Şimdi sırasıyla, class'ımız içindeki fonksiyonların ne iş yaptığına bakalım.

1) Kurucu fonksiyon:
function __construct() {      
    $this->dsn = 'mysql:host=localhost;dbname=veritabaniadi;charset=utf8';
    $this->user = 'root';
    $this->password = '1234';
}
Bu fonksiyon ile, veritabanına bağlanmak için gerekli verileri tanımlıyoruz. Örnek olarak bizim host'umuz localhost, veritabanımızın adı veritabaniadi, kullanıcı adımız root, şifremiz 1234'tür.

2) Bağlantı açıp kapatan fonksiyonlar:
private function baglantiAc() {
    try { $this->db = new PDO($this->dsn, $this->user, $this->password); }
    catch (PDOException $e) {echo 'Veritabanı bağlantısı başarısız oldu: '. $e->getMessage();}
}
private function baglantiKapat() {
    $this->db = null;
}
Bu iki fonksiyonu private olarak tanımladım çünkü dışarıdan veritabanına bağlantı işlerine karışılmasın istedim. Siz isterseniz private kısmını silebilirsiniz (veya public olarak değiştirebilirsiniz).

3) Veri ekleyen fonksiyonumuz:
function ekle($tablo, $veriler) {
    $sonuc = 0;
    $alan1 = "";
    $alan2 = "";
    foreach ($veriler as $anahtar => $deger) {
        $alan1 .= $anahtar . ",";
        $alan2 .= ":".$anahtar.",";
    }
    $alan1 = substr($alan1,0,strlen($alan1)-1);
    $alan2 = substr($alan2,0,strlen($alan2)-1);
    $this->baglantiAc();
    $query = $this->db->prepare("INSERT INTO ".$tablo." (".$alan1.") VALUES (".$alan2.")");
    $query->execute($veriler);
    if ( $query ) $sonuc = $this->db->lastInsertId(); else $sonuc = 0;
    $this->baglantiKapat();
    return $sonuc;
}
Bu fonksiyon, kendisine gönderilen diziyi parçalayıp SQL sorgusuna benzeterek veritabanına işletmektedir. (SQL Injection güvenlik açığından bizi PDO korumaktadır)
Fonksiyon verileri ekledikten sonra, son eklediği satırın ID'sini döndürmektedir. Fonksiyonun nasıl kullanılacağının örneğini aşağıda örnekler kısmında bulabilirsiniz.

4) Veri güncelleyen fonksiyonumuz:
function guncelle($tablo, $veriler, $where="") {
    $sonuc = "";
    $alan = "";
    foreach ($veriler as $anahtar => $deger) $alan .= $anahtar . "= :".$anahtar.",";
    $alan = substr($alan,0,strlen($alan)-1);
    if($where!="") $where = " WHERE ".$where;
    $this->baglantiAc();
    $query = $this->db->prepare("UPDATE ".$tablo." SET ".$alan.$where);
    $update = $query->execute($veriler);
    if ( $update ) $sonuc = $query->rowCount(); else $sonuc = 0;
    $this->baglantiKapat();
    return $sonuc;
}
Fonksiyonumuz, kendisine gönderilen diziyi ve WHERE koşullarını alarak SQL sorgusuna çeviriyor ve bunu veritabanına işletiyor. Sonuç olarak da bu işlemden kaç adet satırın etkilendiğini döndürüyor.

5) ID değerine göre verileri güncelleyen fonksiyonumuz:
function idGuncelle($tablo, $veriler, $id) {
    $sonuc = 0;
    $alan = "";
    foreach ($veriler as $anahtar => $deger) $alan .= $anahtar . "= :".$anahtar.",";
    $alan = substr($alan,0,strlen($alan)-1);
    $veriler['id'] = (int)$id;
    $this->baglantiAc();
    $query = $this->db->prepare("UPDATE ".$tablo." SET ".$alan." WHERE id=:id");
    $update = $query->execute($veriler);
    if ( $update ) $sonuc = 1; else $sonuc = 0;
    $this->baglantiKapat();
    return $sonuc;
}
Bazen (aslında çoğu zaman) ID değerine göre güncelleme yaparız. Bu durumda yeniden WHERE koşulu yazmamıza gerek kalmasın diye böyle bir fonksiyon oluşturdum. Fonksiyonumuz kendisine gönderilen dizideki verilere göre, gönderilen id'ye sahip satırda güncelleme yapıyor. Burada dikkat edilecek husus, fonksiyonun çalışması için ID sütununun adı "id" olmalıdır. Eğer siz bu sütunu "id" olarak değil de mesela "ID" veya "Id" olarak kullanıyorsanız, yukarıdaki fonksiyonda yalnızca WHERE id= kısmını kendinize göre değiştirmeniz gerekiyor. Fonksiyonumuz güncelleme işlemi tamamsa 1 (true), olmadıysa da 0 (false) döndürüyor.

6) Silen fonksiyon:
function sil($tablo,$where) {
    $this->baglantiAc();      
    $delete = $this->db->exec("DELETE FROM ".$tablo." WHERE ".$where);
    $this->baglantiKapat();
    return $delete;
}
Bu fonksiyonumuz da kendisine gönderilen where koşuluna göre silme işlemi yapar. Sonuç olarak da kaç satırın silindiğini döndürür.

7) ID değerine göre silen fonksiyon:
function idSil($tablo,$id) {
    $sonuc = 0;
    $this->baglantiAc();
    $query = $this->db->prepare("DELETE FROM ".$tablo." WHERE id = :id");
    $delete = $query->execute(array('id' => (int)$id));
    if ( $delete ) $sonuc = 1; else $sonuc = 0;
    $this->baglantiKapat();
    return $sonuc;
}
Fonksiyonumuz kendisine gönderilen ID'ye sahip satırı siliyor.

8) Nihayet, SELECT fonksiyonumuz:
function select($tablo,$diger="") {
    $sonuc = null;
    $this->baglantiAc();
    $query = $this->db->query("SELECT * FROM ".$tablo." ".$diger, PDO::FETCH_ASSOC);
    if ( $query ) $sonuc = $query; else $sonuc = null;
    $this->baglantiKapat();
    return $sonuc;
}
Bu fonksiyonumuz SELECT sorgusu işletir. Sonuçta eğer sorgudan dönen bir sonuç yoksa null döndürür. Varsa, foreach kullanarak satır satır verileri okuyabiliriz.

Şimdi gelelim örneklere:

1) Class'ımızı nasıl çağıracağız?
- Bu class'ı bir php dosyası olarak kaydedin. (veri.php gibi)
- Kurucu fonksiyondaki ayarları kendi veritabanı bağlantınıza göre değiştirin.
  (Kendi host'unuzun IP'si, hendi veritabanı adınız, kendi veritabanı kullanıcı adı ve şifreniz)
- Class'ı kullanacağınız sayfalara php dosyasını çağırın. ( include_once("veri.php"); )
Şimdi de çağırdığımız bu dosyadaki class'dan bir nesne oluşturalım.
$vt = new ebykdrms_Veritabani();
Bu komut ile, class'ımızdan $vt adında bir nesne oluşturmuş olduk. Dilediğimizce kullanabiliriz.

2) Nasıl veri ekleyeceğiz?
$sonuc = $vt->ekle("tablo1",array("isim"=>"Emre","yas"=>27);
Bu kadar. Bu satır $sonuc değişkenimize, veritabanına yeni eklenen son satırın ID değerini atayacaktır. (Mesela echo $sonuc; diyerek bu değeri okuyabilirsiniz.)

3) Nasıl güncelleyeceğiz?
$sonuc = $vt->guncelle("tablo1",array("isim"=>"Emreeee"),"yas"=27);
Bu kadar. Bu komut ile tablo1 adlı tablomuzda yas sütununda değeri 27 olan tüm satırların isim sütunu değerleri Emreeee olarak değişecektir. Bu satır $sonuc değişkenine, kaç adet satırın bu işlemden etkilendiğini atayacaktır. ( echo $sonuc." adet satırda güncelleme yapıldı"; )

4) Direkt ID'ye göre güncelleme yapmak istersek?
$sonuc = $vt->guncelle("tablo1",array("isim"=>"Emreeee"),"id"=1);
Bu şekilde bu işi yapmak mümkün. Ama ID'ye göre güncelleme yapmak sık yapılan bir işlemdir. Bu yüzden class'ımızda bunun için daha pratik bir metot bulunuyor:
$sonuc = $vt->idGuncelle("tablo1",array("isim"=>"Emreeee"),1);
Bu satır, $sonuc değişkeninin değerine eğer güncelleme yapılmışsa 1 (true), aksi halde (mesela böyle bir ID değeri yoksa) 0 (false) atar.
( echo ($sonuc) ? "Güncelleme yapıldı" : "Güncelleme yapılmadı"; )

5) Nasıl sileceğiz?
$sonuc = sil("tablo1","id=1");
$sonuc = idSil("tablo1",1);
Bu iki satır da aynı işi yapmaktadır. İlk satırda WHERE koşullarını (id=1 dediğimiz parametreyi) daha detaylı verebiliriz.
$sonuc değişkenine, bu işlemden etkilenen satır sayısı atanacaktır.
echo "Veritabanından $sonuc adet satır silindi"; )

6) Nasıl veri çekeceğiz?
$sorgu = $vt->select("tablo1","WHERE isim= 'Emre' ORDER BY yas DESC");
Bu şekilde sorgu sonucunu $sorgu değişkenine almış olduk. Peki satırlara nasıl erişeceğiz?
if($sorgu != null) foreach( $sorgu as $satir ) { echo $satir["yas"]."<br />"; }
Sonuç olarak isim değeri Emre olanları yaslarına göre büyükten küçüğe sıralayan bir sorguyla gelen satırların yas sütunu değerlerini alt alta yazdırmış olduk.


Başka bir yazıda görüşmek üzere...





7 yorum:

  1. basit, anlaşılır kolay kullanım.
    teşekkürler

    YanıtlaSil
  2. Merhabalar, öncelikle emeğiniz için çok teşekkür ederim. PHP ile çalışmaya başladım. Yazmış olduğunuz class sql injection için bir koruma sağlamakta mı?https://ileriseviyephp.blogspot.com/logout?d=https://www.blogger.com/logout-redirect.g?blogID%3D4029035616359979658%26postID%3D5258237260930962159

    YanıtlaSil
    Yanıtlar
    1. Evet. PDO'nun SQL Injection açığından koruması için sorguyu doğrudan string üzerinde oluşturmak yerine değişkenleri execute() ile sorguya dahil etmişim. Ama yazıyı yıllar önce oluşturmuşum. Aslında çok daha işlevsel fonksiyonlar yazabilirmişim. Yine de bu fonksiyonları alıp kullanım kolaylığı ve yetenek bakımından geliştirmek mümkün tabi.

      Sil
  3. Merit Casino Review【2021】Firmly Recommended
    Merit is 온카지노 also a part of the well known Malta Gaming 메리트카지노 Authority, so it's hard to believe that it's not as good หารายได้เสริม as some casinos.

    YanıtlaSil

Site Haritası

CodeIgniter Yayınları 1. Merhaba Dünya : CodeIgniter'da Merhaba Dünya yazısını görün... 2. Template Sistemi : CodeIgniter ile sta...