Bu dersimizde PHP PDO‘nun kullanımını öğreneceğiz.
PHP PDO ile veritabanı işlemleri için exec, query ve prepare metotları kullanılmaktadır.
exec Metodu
exec metodu parametre olarak aldığı INSERT, UPDATE, DELETE SQL komutlarını çalıştırır ve geri dönüş değeri olarak eklenen, güncellenen veya silinen kayıt sayısını verir.
exec metodunun geri dönüş değeri sayısal bir değer olduğun için sonuç döndüren veri seçme (SELECT), çekme (SHOW) işlemlerinde kullanılmaz.
<?php try { $baglanti = new PDO("mysql:host=localhost;dbname=dbadi", "dbkullaniciadi", "dbsifre"); $baglanti->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $kayit_sayisi = $baglanti->exec("DELETE FROM kisiler WHERE kisi_sira = 9"); if ($kayit_sayisi > 0) { echo $kayit_sayisi . " kayıt silindi"; } else { echo " kayıt silinemedi"; } } catch (PDOException $e) { die($e->getMessage()); } $baglanti = null; ?>
Metotlar genelde veritabanı sistemine ait karakter seti vb. ayarların yapılmasında kullanılmaktadır.
query Metodu
query metodu parametre olarak aldığı SELECT, INSERT, UPDATE, DELETE gibi SQL komutlarını çalıştırır ve PDOStatement sınıfını döndürür.
<?php try { $baglanti = new PDO("mysql:host=localhost;dbname=dbadi", "dbkullaniciadi", "dbsifre"); $baglanti->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sorgu = $baglanti->query("SELECT * FROM kisiler"); echo "<p>toplam kayıt sayısı: " . $sorgu->rowCount() . "</p>"; print_r($sorgu->fetchAll()); } catch (PDOException $e) { die($e->getMessage()); } $baglanti = null; ?>
SQL sorgusu eğer değer döndürüyorsa yani veri çekme işlemi varsa PDOStatement sınıfındaki fetch, fetchAll, fetchColumn, fetchObject metotları kullanılabilir.
<?php try { $baglanti = new PDO("mysql:host=localhost;dbname=dbadi", "dbkullaniciadi", "dbsifre"); $baglanti->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sorgu = $baglanti->query("INSERT INTO kisiler(kisi_adi, kisi_soyadi, kisi_eposta) VALUES('Yusuf Sefa', 'SEZER', '[email protected]')"); echo "<p>eklenen kayıt sayısı: " . $sorgu->rowCount() . "</p>"; echo "<p>eklenen kayıt ID: " . $baglanti->lastInsertId() . "</p>"; } catch (PDOException $e) { die($e->getMessage()); } $baglanti = null; ?>
Eklenen, güncellenen ve silinen kayıt sayısı için PDOStatement sınıfındaki rowCount metodu, eklenen kayıt sırası için PDO sınıfındaki lastInsertId metodu kullanılmaktadır.
SQL sorgusu dışarıdan bir değer alıyorsa eğer query metodu SQL Injection gibi istenmeyen durumlara neden olabilir.
Dışarıdan değer alan SQL sorguları için prepare (ön hazırlıklı sorgu) metodunun kullanılması çok önemli.
prepare Metodu
prepare metodu parametre olarak aldığı SQL komutlarını güvenli olarak çalıştırmak için hazır hale getirir.
<?php try { $baglanti = new PDO("mysql:host=localhost;dbname=dbadi", "dbkullaniciadi", "dbsifre"); $baglanti->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sorgu = $baglanti->prepare("SELECT * FROM kisiler"); $sorgu->execute(); echo "<p>toplam kayıt sayısı: " . $sorgu->rowCount() . "</p>"; print_r($sorgu->fetchAll()); } catch (PDOException $e) { die($e->getMessage()); } $baglanti = null; ?>
Metot parametre olarak aldığı SQL komutunu işlemek üzere PDOStatement sınıfını oluşturur.
PDOStatement ($sorgu) sınıfı içinde bulunan execute metodu ile SQL komutları çalıştırılır.
SQL sorgusu değer döndürüyorsa yani veri çekme varsa, PDOStatement sınıfındaki fetch, fetchAll, fetchColumn, fetchObject metotları kullanılabilir.
Ön hazırlıklı sorgular çoğunlukla dışarıdan örneğin formdan, değişkenlerden vb. alınan verilerin uygun olarak SQL komutuna eklenmesi için kullanılır.
<?php try { $baglanti = new PDO("mysql:host=localhost;dbname=dbadi", "dbkullaniciadi", "dbsifre"); $baglanti->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sorgu = $baglanti->prepare("INSERT INTO kisiler(kisi_adi, kisi_soyadi, kisi_eposta) VALUES(?, ?, ?)"); $adi = "Celal"; $soyadi = "Yurtcu"; $eposta = "[email protected]"; $sorgu->execute(array($adi, $soyadi, $eposta)); echo "<p>eklenen kayıt sayısı: " . $sorgu->rowCount() . "</p>"; echo "<p>eklenen kayıt ID: " . $baglanti->lastInsertId() . "</p>"; } catch (PDOException $e) { die($e->getMessage()); } $baglanti = null; ?>
Benzer olarak özel karakter (?) yerine isimli parametrede (:isimli_parametre) kullanılabilmektedir.
<?php $sorgu = $baglanti->prepare("INSERT INTO kisiler(kisi_adi, kisi_soyadi, kisi_eposta) VALUES(:benim_adim, :benim_soyadim, :benim_epostam)"); $sorgu->execute( array( ':benim_adim' => $adi, ':benim_soyadim' => $soyadi, ':benim_epostam' => $eposta) ); ?>
SQL komutunun içinde parametrelere (? veya :isimli_parametre) execute, bindParam veya bindValue metodu ile veriler güvenli bir biçimde yerleştirilebilir.
bindParam Metodu
bindParam metodu prepare metodu içindeki özel parametrelere (? veya :isimli_parametre) verileri güvenli biçimde yerleştirir.
Metodun ilk parametresi ön hazırlık sorguya göre değer alır, ikinci parametresi dışarıdan alınacak değerin değişkenini belirtir, üçüncü parametre ise verinin tipini belirtmek için kullanılır.
Metodun üçüncü parametresine girilen:
PDO::PARAM_INT – sayısal veri,
PDO::PARAM_STR – metinsel veri,
PDO::PARAM_LOB – binary veri,
PDO::PARAM_INPUT_OUTPUT – saklı yordam girdi / çıktı verisi,
PDO::PARAM_NULL – NULL veri tipi olduğunu belirtir.
Ayrıca çok kullanılmayan dördüncü uzunluk parametresi ve beşinci veritabanı sistemi ayar parametresi mevcuttur.
<?php try { $baglanti = new PDO("mysql:host=localhost;dbname=dbadi", "dbkullaniciadi", "dbsifre"); $baglanti->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sorgu = $baglanti->prepare("INSERT INTO kisiler(kisi_adi, kisi_soyadi, kisi_eposta) VALUES(?, ?, ?)"); $sorgu->bindParam(1, $adi, PDO::PARAM_STR); $sorgu->bindParam(2, $soyadi, PDO::PARAM_STR); $sorgu->bindParam(3, $eposta, PDO::PARAM_STR); $adi = "Celal"; $soyadi = "Yurtcu"; $eposta = "[email protected]"; $sorgu->execute(); echo "<p>eklenen kayıt sayısı: " . $sorgu->rowCount() . "</p>"; echo "<p>eklenen kayıt ID: " . $baglanti->lastInsertId() . "</p>"; } catch (PDOException $e) { die($e->getMessage()); } $baglanti = null; ?>
Benzer olarak özel karakter (?) yerine isimli parametrede (:isimli_parametre) kullanılabilir.
<?php $sorgu = $baglanti->prepare("INSERT INTO kisiler(kisi_adi, kisi_soyadi, kisi_eposta) VALUES(:benim_adim, :benim_soyadim, :benim_epostam)"); $sorgu->bindParam(':benim_adim', $adi, PDO::PARAM_STR); $sorgu->bindParam(':benim_soyadim', $soyadi, PDO::PARAM_STR); $sorgu->bindParam(':benim_epostam', $eposta, PDO::PARAM_STR); ?>
bindValue Metodu
bindValue metodu bindParam ile aynı işleve sahiptir. Ancak bindParam metodunda çok kullanılmayan dördüncü ve beşinci parametreler yoktur.
Metot bindParam metodunda olmayan doğrudan değer atama yapmaya da imkan vermektedir.
<?php try { $baglanti = new PDO("mysql:host=localhost;dbname=dbadi", "dbkullaniciadi", "dbsifre"); $baglanti->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $sorgu = $baglanti->prepare("INSERT INTO kisiler(kisi_adi, kisi_soyadi, kisi_eposta) VALUES(?, ?, ?)"); $sorgu->bindValue(1, 'Celal', PDO::PARAM_STR); $sorgu->bindValue(2, 'Yurtcu', PDO::PARAM_STR); $sorgu->bindValue(3, '[email protected]', PDO::PARAM_STR); $sorgu->execute(); echo "<p>eklenen kayıt sayısı: " . $sorgu->rowCount() . "</p>"; echo "<p>eklenen kayıt ID: " . $baglanti->lastInsertId() . "</p>"; } catch (PDOException $e) { die($e->getMessage()); } $baglanti = null; ?>
Benzer olarak özel karakter (?) yerine isimli parametrede (:isimli_parametre) kullanılabilir.
<?php $sorgu = $baglanti->prepare("INSERT INTO kisiler(kisi_adi, kisi_soyadi, kisi_eposta) VALUES(:benim_adim, :benim_soyadim, :benim_epostam)"); $sorgu->bindValue(':benim_adim', 'Celal', PDO::PARAM_STR); $sorgu->bindValue(':benim_soyadim', 'Yurtcu', PDO::PARAM_STR); $sorgu->bindValue(':benim_epostam', '[email protected]', PDO::PARAM_STR); ?>
PDO sınıfı içinde hata yönetimi için errorCode, errorInfo ve SQL Injection gibi istenmeyen durumlardan korunmak quote metotları kullanılabilir.
errorCode ve errorInfo Metotları
PDO ayarları ile SQL hatalarının try-catch bloğuna yönlendirilmediği durumlarda errorCode ve errorInfo metotları ile hata yönetimi yapılabilir.
<?php $baglanti = new PDO("mysql:host=localhost;dbname=dbadi", "dbkullaniciadi", "dbsifre"); $baglanti->exec("SELECT *"); if ($baglanti->errorCode() != null) { $hata = $baglanti->errorInfo(); die("Hata Kodu: " . $hata[0] . "<br /> hata no: " . $hata[1] . "<br /> hata açıklama: " . $hata[2]); } ?>
Genelde try-catch ile hata yönetimi kullanıldığından bu metotlar hataları kayıt altına alma (loglama) işlemlerinde kullanılabilir.
quote Metodu
PDO sınıfındaki exec ve query metotları SQL Injection gibi istemeyen durumlara karşı savunmasızdır.
exec ve query metotları SQL komutlarına dışarıdan değer alıyorsa quote metodu ile istenmeyen durumlara karşı koruma sağlanır.
<?php try { $id = "40asdasd'<"; $baglanti = new PDO("mysql:host=localhost;dbname=dbadi", "dbkullaniciadi", "dbsifre"); $baglanti->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $id = $baglanti->quote($id, PDO::PARAM_INT); $kayit_sayisi = $baglanti->exec("DELETE FROM kisiler WHERE kisi_sira = $id"); if ($kayit_sayisi != 0) { echo $kayit_sayisi . " kayıt silindi."; } else { echo " kayıt silinemedi."; } } catch (PDOException $e) { die($e->getMessage()); } $baglanti = null; ?>