ile

PHP ile içerik yönetim sistemi – 4 Sınıflarımızı yazmaya başlayalım.

sinif-ogretmenligi-bolumu_clip_image006

Bir önceki örneğimizde sınıfımızdaki metodların içlerini boş bırakmıştık. Şimdi tek tek bu metodların içlerini dolduracağız. Öncelikle veritabanına bağlanacağız. Ancak bu bağlantıyı, sınıf çalışıyorken bir değişkende tutmamız gerek.

[code language=”php”] /**
* Veritabanı bağlantısını tutacak olan değişken.
*
* @var PDO
*/
private $db;

/**
* Veritabanına bağlanmaya yarayan metod
*
* @param string host Veritabanı sunucusunun adresi
* @param string dbname Veritabanı adı
* @param string username Kullanıcı adı
* @param string password Parola
* @return string bağlanılabildiyse doğru, bağlanamadıysa hata mesajı döndürsün.
*/
public function connect($host, $username, $password, $dbname){
try {
return $this->db = new PDO("mysql:host=".$host.";dbname=".$dbname."", "".$username."", "".$password."");
} catch ( PDOException $e ){
return $e->getMessage();
}
}
[/code]

Korkuttu mu? Korkutmasın. Tek tek bakalım:

  1. Sınıfımızın genelinde kullanacağımız $db değşkenini tanımladık
  2. Fonksiyonun içine kullanıcı adı, parola, veritabanı ismi ve sunucu adresini girdik
  3. Yeni bir veritabanı bağlantısı oluşturduk.
  4. Bağlanamazsa, hata mesajını metodun çıktısı olarak vermesini (return etmesini) sağladık.

Şimdi ekleme, güncelleme, silme ve listeleme ve gösterme metodlarını dolduralım.

[code language=”php”] /**
* Girdi ekleyen metod, verilerin kaydedilmesini sağlar.
*
* @param string $title Girdi başlığı
* @param string $content Girdi içeriği
* @param int $category_id Girdi kategorisinin benzersiz kimliği
* @return bool eklendiyse doğru, eklenemediyse yanlış değer döndürsün
*/
public function add($title, $content, $category_id){

// Tarih içeren alanları elle girmiyoruz. Sistemden doğrudan isteyen fonksiyonumuz var.
$date = $this->getDate();

// Önce veritabanı sorgumuzu hazırlayalım.
$query = $this->db->prepare("INSERT INTO posts SET title=:baslik, content=:icerik, created=:created, category_id=:category, updated=:updated");

$insert = $query->execute(array(
"baslik"=>$title,
"icerik"=>$content,
"category"=>$category_id,
"created"=>$date,
"updated"=>$date
));

if($insert){
// Veritabanı işlemi başarılı ise sınıfın objesine ait değişkenleri değiştirelim
$this->id = $this->db->lastInsertId();
$this->title = $title;
$this->content = $content;
$this->created = $date;
$this->updated = $date;
$this->category_id = $category_id;

return true;
}
else{
return false;
}
}
[/code]

Yine işlemimizi adım adım inceleyelim.

  1. Önce daha önceden hazırlamış olduğumuz sorguları oluşturduk ve değişkenleri içeri yerleştirdik.
  2. Daha sonra execute metoduyla sorguyu çalıştırdık.
  3. En sonunda eğer işlem başarılı oldu ise, sınıftan ürettiğimiz objeye ait değişkenleri değiştirdik. (Bu cümleyi anlayamadıysanız sorun değil.)

Güvenlik için dışarıdan gelen $title ve $content verisini de sorguya execute metoduyla dahil ettik ki, sistemimize hacker’lar saldırmasın. Değişkenleri SQL sorgularına hiçbir kontrol olmadan sokmak, gerizekalılıktır arkadaşlar. Örneğin elimizdeki sorgu, SELECT * FROM users WHERE id=’osman’ AND password = $password olsun. $id verisi geldiğinde kullanıcıyı sisteme sokalım. Eğer password dediğimiz veri string değil de, ” OR ‘1’=’1′ gibi bir ifadeyse sorgunuz şöyle olur: SELECT * FROM users WHERE id=’osman’ password =” OR ‘1’=’1′; Eleman pat diye sisteminize girer. Yani msql fonksiyonlarını güvenlik için kullanmıyorum ve anlatmıyorum. PDO kütüphanesini kullanmamızın sebebi de bu.

Genel olarak veritabanı kullanan işlemlerimiz neredeyse aynı.

[code language=”php”]  /**
* Tek bir girdinin gösterilmesini sağlayan method
*
* @param int $id Girdinin benzersiz index’i
* @return array gösterilebildyise dizi türünde verileri döndürsün, gösterilemediyse false, yanlış değeri döndürsün
*/
public function view($id){

// Eğer daha önceden sorgu işlemi yapıldıysa, sınıf objesine yazılmıştır.
if($id == $this->id){
return array("id"=>$this->id,"title"=>$this->title,"content"=>$this->content, "category_id"=>$this->category_id, "created"=>$this->created, "updated"=>$this->updated);
}
else{
// Buradan anlıyoruz ki veri henüz çekilmemiş. Veriyi çekmeye başlayalım
$query = $this->db->prepare("SELECT * FROM posts WHERE id=:id");
$query->execute(array(‘:id’=>$id));

if($query){
$result = $query->fetch(PDO::FETCH_ASSOC);

$this->id = $result[‘id’];
$this->title = $result[‘title’];
$this->content = $result[‘content’];
$this->created = $result[‘created’];
$this->updated = $result[‘updated’];
$this->category_id = $result[‘updated’];

return $result;
}
}

// Eğer iki işlem de başarısız olduysa, false, yanlış değer döndürelim.
return false;
}
[/code]

Yine adım adım inceleyelim. Önce sınıfımızdan yaratılan objemize daha önceden verinin çekilip çekilmediğini kontrol ettik. Veri çekildiyse sorun yok, doğrudan değer döndürebiliriz. Yok eğer çekilmediyse, o zaman klasik pdo sorgumuzu oluşturduk. PDO::FETCH_ASSOC ifadesiyle sonucu alan isimlerinin dizi anahtarları şeklinde içeren bir dizi olarak çekmek istediğimizi belirttik. Bu ayarla ilgil başka özellikle de var, her zamanki gibi anlatmıyorum, siz ihtiyacınız olduğunda araştırırsınız.

Metodlarımızı doldurmaya devam edelim. Tüm verileri çeken index metodumuzu oluşturalım:

[code language=”php”] /**
* Tüm girdilerin listelenmesini sağlayan metod.
*
* @return bool listelenebildiyse doğru, listelenemediyse yanlış değer döndürsün
*/
public function index(){
$query = $this->db->prepare("SELECT * FROM posts");
$query->execute();
if($query){
// Buradaki fetchAll metoduyla tüm değeleri diziye çektik.
return $query->fetchAll(PDO::FETCH_ASSOC);
}
else
{
return false;
}
}
[/code]

Buradaki tek fark şu, fetchAll metodu kullanarak, tüm cevap satırlarını dizi olarak döndürüyoruz. Sırada girdileri düzenlediğimiz metod var.

[code language=”php”] /**
* Girdi düzenleyen metod. Verilen Id bilginse göre, alınan bilgi ile sistemdeki bilgiyi değiştiren
* güncelleyen metod.
*
* @param int $id Girdinin benzersiz index’i
* @return bool düzenlendiyse doğru, eklenemediyse yanlış değer döndürsün
*/
public function edit($id, $title, $content, $category_id){

// Tarih içeren alanları elle girmiyoruz. Sistemden doğrudan isteyen fonksiyonumuz var.
$date = $this->getDate();

// Önce veritabanı sorgumuzu hazırlayalım.
$query = $this->db->prepare("UPDATE posts SET title=:baslik, content=:icerik, category_id=:category, updated=:updated WHERE id=:id");

$update = $query->execute(array(
"baslik"=>$title,
"icerik"=>$content,
"category"=>$category_id,
"updated"=>$date,
"id"=>$id
));

if ( $update ){
return true;
}
else
{
return false;
}
}
[/code]

Daha önceki veritabanı sorguları bölümünden hatırlayacağımız gibi, verileri düzenlerken UPDATE komutunu çalıştırıyoruz. Yine değişkenlerimizi ve sorgumuzu korumak adına prepare (hazırla) ve execute (çalıştır) metodlarını kullandık. Son bir işlemimiz kaldı. O da verileri silmek.

[code language=”php”] /**
* Girdi silen metod, verilerin silinmesini sağlar.
* Geri dönüşü yoktur.
*
* @param int $id Girdinin benzersiz index’i
* @return bool silindiyse doğru, eklenemediyse yanlış değer döndürsün
*/
public function delete($id){
$query = $this->db->prepare("DELETE FROM posts WHERE id = :id");
$delete = $query->execute(array(
‘id’ => $id
));
}
[/code]

Girdimizi basitçe sildikten sonra sınıfı nasıl kullanacağımıza bir göz atalım. Aynı klasörde index.php isimli bir dosya yaratalım.

[code language=”php”]<?php
$post = new Posts();
$post->connect(‘localhost’,’kullanici’,’parola’,’merakli’);
$post->add(&quot;CMS&quot;, &quot;Neden bu kadar çok kısaltma kullanıyorsun ey meraklibilisimci.com???&quot;,1);
$post->add(&quot;PHP&quot;, &quot;AngularJS diye bişey çıkmış&quot;,1);
$post->edit(1, &quot;OOP’ye giriş&quot;, &quot;OOP’yi çok severiz. OOP kullanmamak çok sıkıntı çıkarır, spaghetti insanın midesini bozar.&quot;,1);
$post->delete(2);
var_dump($post->index());
?>[/code]

Önce new komutuyla sınıfımızdan bir obje ürettik. Bağlatı işlemi yaptık. İki makale ekledik, 1 numaralı id’ye sahip olan makaleyi güncelledik, ve 2 numaralı id’ye sahip olan makaleyi de sildik. En son olarak da ekrana veritabanımıza eklediğimiz verilerin çıktısı gelcek. Görüntüsü de şöyle olacak:

[code language=”php”]array (size=1)
0 =>
array (size=6)
‘id’ => string ‘1’ (length=1)
‘title’ => string ‘OOP’ye giriş’ (length=10)
‘content’ => string ‘OOP’yi çok severiz. OOP kullanmamak çok sıkıntı çıkarır, spaghetti insanın midesini bozar.’ (length=99)
‘category_id’ => string ‘1’ (length=1)
‘created’ => string ‘2014-08-18 00:00:00’ (length=19)
‘updated’ => string ‘2014-08-18 00:00:00’ (length=19)
[/code]

Sınıfımızın son hali https://github.com/mtkocak/merakli/blob/d1cb92d2724434030d2c3be2a120ac74b9ae746c/posts.php

Şu ana kadar tek bir sınıf ve veritabanı tablosu için back-end’de yani sunucu tarafında yapmamız gerekenleri gördük, veriyi ekledik, düzenledik, sildik, değiştirdik ve listeledik. Daha sonra diğer sınıfları oluşturarak devam edeceğiz. Siz de teme mantığı anladığınız üzere, kendi sınıflarınızı yazmaya başlayabilirsiniz.

 

Kaynaklar

  1. http://www.erbilen.net/816-pdo-kullanimi.html
  2. http://omerozkan.net/oop-kapsulleme/
  3. http://omerozkan.net/oop-kalitim/
  4. http://omerozkan.net/oop-polimorfizm/
  5. http://omerozkan.net/oop-soyutlama/
  6. http://www.yazilimciblog.com/oop-temel-prensipleri/
  7. http://www.csharpnedir.com/articles/read/?id=101http://www.kazimapanoglu.com/makaleler/csharp/11-csharp-oop/4-encapsulation
  8. https://semihkirdinli.wordpress.com/category/object-oriented-programming/

Yorumla

Yorum

  1. connect fonksiyonunu yazarken ayrı bir fonksiyon yerine

    [php]
    public function __construct($host, $username, $password, $dbname){
    try {
    return $this->db = new PDO("mysql:host=".$host.";dbname=".$dbname."", "".$username."", "".$password."");
    } catch ( PDOException $e ){
    return $e->getMessage();
    }
    }
    [/php]

    olsa daha iyi olurdu. böylece Class’ı sayfamıza dahile ederken içinde ayrı fonksiyon çalıştırmaz ve ;

    [php]$db = new Baglan(‘localhost’,’db’,’root’,’password’);[/php]

    şeklinde işlem yapabilirdik 🙂

    • __construct() gibi magic oop fonksiyonlarını henüz anlatmadığım için o şekilde yazmadım. oop kavramları başlığında dediğinizi yapacağım. çok teşekkürler..