Merhaba arkadaşlar,
Phphocasi.com.tr’ da yayınladığımız Codeigniter Dersleri setimize 7. yazımızla devam ediyoruz. Önceki dersimizde Codeigniter Veritabanı İşlemleri konusundan bahsettik ve Active Record ile CRUD işlemleri yaptık. Önceki yazımızın da sonlarında değindiğim gibi Controller içinde veritabanına erişim için Active Record kodları yazdık. Dolayısıyla MVC mimarisine aykırı bir tutum sergilemiş olduk. Bu sorunun önüne geçmek için bu dersimizde Model Dosyası kullanımını öğreneceğiz.
Bu dersi anlatırken önceki dersimde anlattığım projenin üzerinde gideceğiz. Dolayısıyla önceki yazımı okumadıysanız eğer yazıya buradan ulaşabilirsiniz. Bu dersten itibaren View’ e veri’ yi nesne halinde göndereceğiz. Fakat eğer siz isterseniz dizi ile de gönderebilirsiniz. Bu iki kullanım da aynı amaca hizmet eder fakat bana göre nesne ile gönderme yönteminde kodların okunabilirliği daha fazla olduğundan ben nesne ile gönderme yöntemini tercih edeceğim.
Model Dosyası Oluşturmak
- Model dosyamızı hepinizin de tahmin edeceği üzere application klasörü altında bulunan models klasörünün altına oluşturacağız.
- Oluşturacağımız dosya adını Egitmenler_model.php yapıyoruz. Bu dosyanın içinde Egitmenler_model adında bir class oluşturup, CI_Model adındaki sınıfı Egitmenler_model sınıfımıza extend ediyoruz. Genellikle isim benzerliklerini ve proje büyüdükçe oluşabilecek kafa karışıklıklarını önlemek adına dosyalarının sonuna Model dosyası olduğunu belirtmek için _model eki konulur, ancak bu bir zorunluluk değildir. Eğer siz de şu ana kadar yaptığım işlemleri adım adım yaptıysanız kodlarınız aşağıdaki gibi olmalıdır.
- Bu şekilde model dosyasını oluşturduk şimdi ise önceki derste yazdığımız Active Record kodlarını model dosyasına taşıyacağız ve bu kodları Controller tarafında çağırarak kullanacağız.
Listeleme işlemi
Önceki dersimizde verileri listeleme işlemini aşağıdaki gibi yapmıştık.
public function index() { $satirlar=array(); $satirlar["egitmenler"]=$this->db->get("egitmenler")->result(); $this->load->view("egitmenler",$satirlar); }
Şimdi ise bu kodu refactor edeceğiz ve Active Record kodumuzu oluşturduğumuz Egitmenler_model.php dosyasına taşıyacağız. Model dosyamızın içine GetAll adında bir metod oluşturalım. GetAll metodu bize veritabanındaki tüm eğitmenleri döndürecek olan bir metod olacak. Bu metodun içinde ise sadece $this->db->get(“egitmenler”)->result(); satırı bulunacak. Bu işlemden sonra model dosyamızın içinde yazan kodlar aşağıdaki gibi olacaktır.
<?php class Egitmenler_model extends CI_Model { public function GetAll(){ return $this->db->get("egitmenler")->result(); } }
Model dosyamızda bulunan GetAll metodunu da yazma işlemini de tamamladığımıza göre artık sıra model dosyamızı Controller tarafında kullanmaya geldi. Fakat ondan önce Action’ umuzda kullanabilmek için model dosyasının nasıl yükleneceğinden bahsedeceğim.
Model dosyasını yüklemek
Model dosyamızı 3 farklı erişim seviyesinde yükleyebilir ve kullanmak istediğimiz Controller’ da kullanabiliriz. Bu 3 erişim seviyesini ve yöntemini küçükten büyüğe sıralayacak olursam
- Action içinde
$this->load->model("Modelismi_model");
şeklinde yükleyebilir ve sadece yüklediğimiz Action içinde modelde bulunan metodları kullanabiliriz.
- Yükleyeceğimiz bir modelin bir Controller içindeki tüm Actionlarda kullanılmasını istiyorsak, Controller içinde bir constructor (yapıcı method) yardımıyla modelimizi yükleriz ve Controller içindeki tüm Actionlar tarafından bu modelin kullanılabilmesini sağlarız. Bunun yöntemi ise aşağıdaki gibidir.
public function __construct() { parent::__construct(); $this->load->model("Modelismi_model"); }
Burda dikkat etmeniz gereken nokta model yükleme işlemi için parent::__construct(); satırını yazmamız gerektiğidir. Bu şekilde bir kullanım yüklediğimiz model dosyası Controller içinde tüm Actionlar tarafından kullanılıyorsa mantıklıdır. Fakat Model dosyası nadir kullanılıyorsa Model dosyalarının sadece kullanıldığı Action içinde kullanılması kaynakların verimli tüketilmesi açısından önemlidir.
- Yükleyeceğimiz Model dosyasının proje genelinde yüklenmesini istiyorsak bunu config klasörü altında bulunan autoload.php dosyası içinde yapmalıyız. Bu dosya içinde bulunan $autoload adlı dizinin model indisine proje genelinde kullanılmasını istediğimiz Model dosyalarının isimlerini yazarak proje genelinde yüklenmelerini sağlarız. Bu işlem aşağıdaki gibi
$autoload["model"] = array("Modelismi_model,Modelismi2_model,Modelismi3_model");
şeklinde yapılır. Bu kullanım eğer model dosyası proje genelinde kullanılacaksa doğru bir kullanımdır. Onun dışında ise Model dosyasının Controller ya da Action içinde yüklenmesi kaynakların verimli kullanılması adına daha mantıklıdır.
Listemele işlemini düzenleyelim
Bu anlatımdan sonra Index Actionumuzu refactor edebiliriz artık. Index Actionumuzda Egitmenler model’ ini yükleyip GetAll metodunu aşağıdaki gibi kullanabiliriz.
public function index() { $satirlar=array(); $this->load->model("Egitmenler_model"); $satirlar["egitmenler"]=$this->Egitmenler_model->GetAll(); $this->load->view("egitmenler",$satirlar); }
Yukarda ki kodun da değişken isimleri ve verinin View’ e gönderilme anlamında (nesne ile göndereceğim için) refactor edilmeye ihtiyacı var. Bundan sonraki yazılarımda da View’ e göndereceğim verileri $viewData adında stdClass türünde bir nesne ile göndereceğim. Önceki yazımda da belirmiştim veritabanındaki kayıtlarımız codeigniter tarafında bir stdClass nesnesi şeklinde dönüyor demiştik. Bu kullanım aşağıdaki gibidir.
public function index() { $viewData=new stdClass(); $this->load->model("Egitmenler_model"); $viewData->egitmenler=$this->Egitmenler_model->GetAll(); $this->load->view("egitmenler",$viewData); }
Yukarda ki kodda da gördüğünüz üzere Model dosyasını Action içinde yüklemeyi tercih ettim. Fakat bu tercihim yazının ilerleyen kısımlarında projenin durumuna göre değişiklik gösterecektir.
Ekleme işlemini düzenleyelim
Öncelikle Egitmenler_model.php dosyamızın içine eğitmen eklememiz için gerekli metodu yazacağız. Fakat bu model dosyasında sık kullandığımız yapılar olduğundan kod tekrarının önüne geçecek düzenlemelere yazının ilerleyen kısımlarında gideceğiz. Şimdi ilk olarak Egitmenler_model.php dosyasında Add adında bir metod oluşturacağız ve bu metod parametre olarak $data (View’ den Controller’ a gönderilen verileri içeren bir dizi) dizisi alacak. Bu işlemlerden sonra model dosyamızın içeriği aşağıdaki gibi olacaktır.
<?php class Egitmenler_model extends CI_Model { public function GetAll(){ return $this->db->get("egitmenler")->result(); } public function Add($data=array()){ return $this->db->insert("egitmenler",$data); } }
Controller tarafında yapacağımız değişiklik ise post_add Action’ unda Model dosyasında bulunan Add metodunu kullanmak olacak. post_add Action’ una ait kodlar ise aşağıdaki gibi olacaktır.
public function post_add(){ $eklenecek_veri=array( "fullname" =>$this->input->post("fullname"), "age" =>$this->input->post("age"), "description" =>$this->input->post("description"), "isActive" =>empty($this->input->post("isActive"))? 0:1, ); $this->load->model("Egitmenler_model"); $insert=$this->Egitmenler_model->Add($eklenecek_veri); if ($insert>0){ redirect(base_url("Welcome")); //Ekleme işlemi başarılıysa egitmenler View" ine dönecek die(); }else{ redirect(base_url("Welcome/get_add")); // Ekleme işlemi başarısızsa ekleme sayfasında kalacaz die(); } }
Şimdi yaptığımız işlemi test edelim. Yani yeni bir eğitmen ekleyelim
Formu yukardaki gibi doldurup post ettiğimizde karşılaşacağımız görüntü aşağıdaki gibi olacaktır.
Güncelleme işlemini düzenleyelim
Güncelleme işleminde hem get_update hem de post_update Action’ unda Active Record kodları kullandığımızdan bu iki Action’ unda düzenlenmesi gerekir.
İlk olarak get_update Action’ unu düzenleyelim. Action içinde Action’ un parametre aldığı $id ile tek bir eğitmeni çeken bir Active Record kodu bulunmakta. Dolayısıyla Egitmen_model dosyasında $id parametre alıp tek satır değer döndüren bir metoda ihtiyacımız var ve bu metodumuzun adı da Get olsun. Get metodumuza ait kodlar ve bu metodun Controller tarafında kullanımı aşağıdaki gibi olacaktır.
<?php class Egitmenler_model extends CI_Model { public function GetAll(){ return $this->db->get("egitmenler")->result(); } public function Add($data=array()){ return $this->db->insert("egitmenler",$data); } public function Get($id){ return $this->db->where("Id",$id)->get("egitmenler")->row(); } }
Şimdi ise controller’ ımızda Get metodunu kullanalım. Fakat öncelikle Model’ imizi load etmeyi unutmayalım
public function get_update($id){ $this->load->model("Egitmenler_model"); $guncellenecek_egitmen["egitmen"]=$this->Egitmenler_model->Get($id); $this->load->view("egitmen_guncelle",$guncellenecek_egitmen); }
Bu işlemi son eklediğimiz egitmenin satırında bulunan güncelle linkine tıklayarak denediğimizde karşılaşacağımız görüntü aşağıdaki gibi olacaktır.
Şimdi sıra post_update Action’ unda düzenleme yapmaya geldi. Bunun için ilk olarak Model dosyamıza Action’ umuzda kullanacağımız Update metodunu oluşturalım. Model dosyamızda yazacağımız Update güncellenecek eğitmene ait verilerin bulunduğıu $data adında bir diziyi parametre alacak ve Update metodumuz aşağıdaki gibi olacaktır.
<?php class Egitmenler_model extends CI_Model { public function GetAll(){ return $this->db->get("egitmenler")->result(); } public function Add($data=array()){ return $this->db->insert("egitmenler",$data); } public function Get($id){ return $this->db->where("Id",$id)->get("egitmenler")->row(); } public function Update($data=array()){ return $this->db->where("Id",$data["Id"])->update("egitmenler",$data); } }
Şimdi ise Update metodumuzu post_update Action’ u içinde kullanalım. Fakat yine Model dosyamızı load etmeyi unutmayalım. Yoksa hata ile karşılaşırız.
public function post_update(){ $guncellenecek_veri=array( "Id" =>$this->input->post("Id"), "fullname" =>$this->input->post("fullname"), "age" =>$this->input->post("age"), "description" =>$this->input->post("description"), "isActive" =>empty($this->input->post("isActive"))? 0:1, ); $this->load->model("Egitmenler_model"); $update=$this->Egitmenler_model->Update($guncellenecek_veri); if ($update>0){ redirect(base_url("Welcome")); die(); }else{ redirect(base_url("Welcome/get_update/".$guncellenecek_veri["Id"])); die(); } }
Controller’ ımızı da düzenledikten sonra bu işlemi test etmek için eklediğimiz son eğitmenin yaşını 25 olarak güncelleyelim. Yapılacak işlemler sırasıyla
Bu sayfayı post edersek aşağıdaki sayfa ile karşılaşırız.
Silme işlemini düzenleyelim
Bu işleme ait sadece bir Action olduğundan sadece bu action’ a ait kodları düzenlememiz yeterli olacaktır. İlk olarak Model dosyamızda Delete adında bir method yazalım. Bu method parametre olarak sadece silinecek olan eğitmenin id’ sini alsın. Metoda ait kodlar aşağıdaki gibidir.
public function Delete($id){ return $this->db->where("Id",$id)->delete("egitmenler"); }
Şimdi ise bu metodu delete Action’ umuzda kullanalım.
public function delete($id){ $this->load->model("Egitmenler_model"); $delete=$this->Egitmenler_model->Delete($id); if ($delete>0){ redirect("Welcome"); }else{ echo "Silme işleminde hata..."; } }
Şimdi sıra silme işlemini test etmeye geldi. Listede bulunan değerli eğitmenlerimiz üzerinde bu işlemi test etmek istemiyorum. ? Dolayısıyla bu işlem için bir Test kaydı ekledim. Bu işlemi Test kaydını silerek test edeceğim.
Silme işleminden önce
Silme işleminden sonra
Yavaş yavaş yazımın sonuna doğru yaklaşırken kodlarımızda 2 adet daha düzenleme yapacağız. Bunlardan ilki Controller sayfamız içinde neredeyse her Action içinde Model’ imizi yükledik. Bu işlemi Constructor içinde yapalım ve dolayısıyla otomatik olarak tüm Actionlar içinde modelimiz yüklensin. Bu işlemden sonra Controller’ daki kodlarımız aşağıdaki gibi olacaktır.
<?php defined("BASEPATH") OR exit("No direct script access allowed"); class Welcome extends CI_Controller { public function __construct() { parent::__construct(); $this->load->model("Egitmenler_model"); } public function index() { $viewData=new stdClass(); $viewData->egitmenler=$this->Egitmenler_model->GetAll(); $this->load->view("egitmenler",$viewData); } public function get_add(){ $this->load->view("egitmen_ekle"); } public function post_add(){ $eklenecek_veri=array( "fullname" =>$this->input->post("fullname"), "age" =>$this->input->post("age"), "description" =>$this->input->post("description"), "isActive" =>empty($this->input->post("isActive"))? 0:1, ); $insert=$this->Egitmenler_model->Add($eklenecek_veri); if ($insert>0){ redirect(base_url("Welcome")); //Ekleme işlemi başarılıysa egitmenler View" ine dönecek die(); }else{ redirect(base_url("Welcome/get_add")); // Ekleme işlemi başarısızsa ekleme sayfasında kalacaz die(); } } public function get_update($id){ $guncellenecek_egitmen["egitmen"]=$this->Egitmenler_model->Get($id); $this->load->view("egitmen_guncelle",$guncellenecek_egitmen); } public function post_update(){ $guncellenecek_veri=array( "Id" =>$this->input->post("Id"), "fullname" =>$this->input->post("fullname"), "age" =>$this->input->post("age"), "description" =>$this->input->post("description"), "isActive" =>empty($this->input->post("isActive"))? 0:1, ); $update=$this->Egitmenler_model->Update($guncellenecek_veri); if ($update>0){ redirect(base_url("Welcome")); die(); }else{ redirect(base_url("Welcome/get_update/".$guncellenecek_veri["Id"])); die(); } } public function delete($id){ $delete=$this->Egitmenler_model->Delete($id); if ($delete>0){ redirect("Welcome"); }else{ echo "Silme işleminde hata..."; } } }
Kodlarda da gördüğünüz üzere kullandığımız Action’ ların hiçbirinde modelimi yüklemeye gerek kalmadan Model dosyamızdaki metodları kullanabildik.
Şimdi ise 2. değişikliği Model dosyamızda yapacağız ve bu değişiklik Model dosyasında hep aynı tablo üzerinde çalışmamız ile alakalı bir değişiklik olacak. Bu değişikliği yapma sebebimiz yarın bir gün tablo ismini değişmek istediğimizde tek tek tüm metodlarda tablo ismini değişmekle uğraşmamak için olacak. Model dosyasının düzenlenmiş hali aşağıdaki gibidir.
<?php class Egitmenler_model extends CI_Model { private $table=""; public function __construct() { $this->table="egitmenler"; } public function GetAll(){ return $this->db->get($this->table)->result(); } public function Add($data=array()){ return $this->db->insert($this->table,$data); } public function Get($id){ return $this->db->where("Id",$id)->get($this->table)->row(); } public function Update($data=array()){ return $this->db->where("Id",$data["Id"])->update($this->table,$data); } public function Delete($id){ return $this->db->where("Id",$id)->delete($this->table); } }
Yukarda yaptığım değişikliği açıklayacak olursam private $table adında bir değişken oluşturduk ve bunu initialize ettik. Daha sonra parametresiz Contructor içinde bu değişkene ait değeri yani tablo ismimizi atamış olduk. Dolayısıyla bundan sonra tabloda olabilecek isim değişikliğinde değişiklik tek bir yerden yapılacak ve her yeri etkileyecek duruma getirilmiş oldu.
Codeigniter Dersleri eğitim setinin 7. yazısını burada noktalıyorum. Bu yazımızda Model Dosyası kullanımı konusundan bahsettik. Konu ile ilgili sorularınızı Mobilhanem Soru&Cevap bölümünden sorabilirsiniz. Bir sonraki dersimde Codeigniter’ da Form validation konusundan bahsedeceğim.
Tüm Codeigniter Dersleri‘ ne buradan ulaşabilirsiniz.
2