Selam,
Geçtiğimiz derste MVC ve REST yapılarına ufak bir giriş yapıp temel oluşturmuştuk. Bu derste biraz daha ilerliyoruz. Bugünkü konularım:
İlk konumuz Controller yapısını görmek ve basit bir controller dosyası oluşturmak.
Bundan önceki derslerde herhangi bir işlem yapmak istediğimde sürekli routes.php
üzerinde çalışıyordum. Sitemin urli için bir route oluşturup, kullanıcı bu urle ulaşınca yapılması gerekenleri bu route içinde belirtiyordum. Ama buraya kadar olan kısımlarda oluşturduğumuz örnek web siteleri 2-3 urle ve birkaç forma sahipti. Gerçek bir web sitesinde binlerce url ve birçok form olabilir. Tüm bunları routes.php
altında toplayıp, yapılacak işlemler için yazılacak kodları düşünürsek routes.php
nin karman çorman bir yapıya bürüneceğini tahmin edebiliriz.
Bu noktada devreye controller dosyalarımız giriyor. app/controllers
dizini açarsak hali hazırda 2 adet controller dosyasının var olduğunu görürüz: BaseController.php
ve HomeController.php
BaseController
dosyasını ana controller dosyamız olarak düşünebiliriz. Oluşturduğumuz controller dosyalarını BaseController
dan “extend” yapıyoruz. Dolayısıyla şimdilik BaseController
dosyasına uzaktan bakıp dokunmamak daha iyi.
HomeController
ise Laravel ile birlikte gelen örnek bir controller dosyası.
<?php class HomeController extends BaseController { public function showWelcome() { return View::make('hello'); } }
3. satırda görüldüğü gibi HomeController
, BaseController
sınıfını kalıtımlamış. (Bu sözcüğü benim uydurduğumu anladınız sanırım)
HomeController
sınıfımız showWelcome
isminde bir fonksiyona sahip ve bu fonksiyonun görevi hello
ismindeki view dosyasını döndürmek.
Şimdi routes.php
dosyasını açarak HomeController
ın showWelcome
fonksiyonunu kullanacağım.
Route::get('/', "HomeController@showWelcome" );
İşte hepsi bu kadar! get()
metoduna ikinci parametre olarak fonksiyon yerine <controller>@<metod>
olarak controller ve metod adını yazmam yeterli.
Homecontroller
içinde yeni bir metod oluşturup routes.php
den bunu çalıştıralım:
class HomeController extends BaseController { public function showWelcome() { return View::make("anasayfa"); } public function hakkimizda(){ return "WEB SANATÇILARININ PHP FRAMEWORK'Ü"; } }
Route::get('hakkimizda', "HomeController@hakkimizda" );
Şimdi de kendimize yeni bir controller oluşturalım. app/controllers
içinde SelamController.php
dosyasını oluşturup içine kodlarımı yazıyorum:
class SelamController extends BaseController{ public function karsilamaMesaji(){ return "Her sözün doğru olmalı; fakat her doğruyu söylemek, doğru değil"; } }
Ve routes.php
içinden bu metodu çalıştırıyorum:
Route::get('/', "SelamController@karsilamaMesaji" );
Route
a gelen parametreleri controllera aktarmamız da mümkün:
routes.php:
Route::get('manav/{meyve?}', "SelamController@manav" );
SelamController.php:
class SelamController extends BaseController{ public function manav($meyve = null){ $meyveler = array("elma", "armut", "muz", "erik"); if($meyve == null) { echo $meyveler[0]. "<br/>"; echo $meyveler[1]. "<br/>"; echo $meyveler[2]. "<br/>"; echo $meyveler[3]; } else { if(in_array($meyve, $meyveler)) return "Bu meyve mevcut: ".$meyve; else return "Bu meyve yarına gelecek"; } } }
Basitçe bir kontroller bu şekilde işliyor. Şimdi seviyeyi biraz daha yükseltip Restful Controllera bakalım.
Projelerimizi sergilemek için bir web sitemiz olduğunu varsayıyorum. Müzik, film, kitap gibi farklı alanlarda projelerimiz olsun. Bu farklı kategorideki projelere ulaşmak için routes.php
de hepsine bir yol tanımlaybiliriz. get("projeler/muzik"),
get("projeler/film"),
get("projeler/kitap")
vb. gibi. Ya da localhost/projeler/
altındaki tüm urlleri ProjelerController
dosyasına bırakabiliriz. Tabii ki bunun için ProjelerController
dosyası oluşturup düzenlememiz gerekecek ama önce routes.php
de localhost/projeler/
altındaki tüm urlleri nasıl ProjelerController
a yönledireceğimize bakalım:
Route::controller("projeler", "ProjelerController");
Bu kod ile localhost/projeler/
altındaki tüm urlleri ProjelerController
içinden kontrol etmemize olanak sağladık. Şimdi ProjelerController
dosyamızı oluşturup ilk ayarlamaları yapıyorum:
class ProjelerController extends BaseController{ public function getIndex(){ return "Hoşgeldiniz! Projelerime göz atmak ister misiniz?"; } }
getIndex
metodu ile localhost/projeler
url adresine ulaşınca bir mesaj döndürmesini istedik. Restful controller ile çalıştığımızda fonksiyonlara isim verirken uymamız gereken bir kural var. İsimlendirmeye hangi HTTP verb ü kullanacaksak onunla başlamalıyız. REST ile ilgili temel konuları geçen derste öğrendiğim şimdi bunlara değinmiyorum.
Şimdi localhost/projeler/muzik
için yapılacak eylemleri belirleyelim. Yine ProjelerController
üzerinde düzenleme yapıyorum:
public function getMuzik(){ return "Müzik projelerimin listesi..."; }
Şimdiye kadar get
kullandık çünkü, ne zaman adres çubuğunda urli girip entera basarsak aslında GET
eylemi gerçekleşiyor.
Eğer yeni bir proje eklemek istersek post
eylemini kullanmalıyız. Sitemizin anasayfasında bir form olduğunu varsayıyorum ve gönder butonuna tıkladığımız zaman projeler/ekle
url adresine yönlenecek. Formumuz basitçe şu şekilde olsun:
{{Form::open( array("url" => "projeler/ekle") )}} {{Form::label("projeAdi", "Proje")}} {{Form::text("projeAdi")}} {{Form::submit("Ekle")}} {{Form::close()}}
Şimdi ProjelerController
içinde bu eylemi düzenleyelim:
public function postEkle(){ return "POST çalıştı"; }
Bu sefer get
değil post
ile metodumuzu isimlendirdik. Çünkü POST
eylemi gerçekleşti.
Şu ana kadar 2 adet Controller tipi öğrendik. İlki standart bir controller tipindeydi ve şu şekilde oluşturuyorduk:
Route::get("/", "HomeController@metodAdi");
İkincisi RESTful Controller şeklindeydi ve şu şekilde tanımlıyorduk:
Route::controller("projeler", "ProjelerController");
RESTful controller ile /projeler
ve onun altındaki tüm urlleri kontrol edebiliyorduk.
Ve son controller tipimize geliyoruz: Resource Controller. “Resource” un ne olduğunu da bir önceki derste öğrenmiştim. Bu bölümde geçen dersteki yemek tarifleri sunan site örneği üzerinden devam edeceğim.
İlk olarak routes.php
den nasıl resource controllera gideceğimize bakalım:
Route::resource("tarifler", "TariflerController");
resource
metoduna ilk parametre olarak yine url ve ikinci parametre olarak yine controller dosyamızın adını gönderiyoruz. Bu ilk adımdı.
Geçen derste öğrendiğim üzere, kaynaklarıma bazı HTTP metodlarıyla müdahale edebiliyordum. Yemek tarifleri sitesi içinde hangi urlde hangi eylemin gerçekleşeceğine dair bir tablo hazırlamıştım. Laravel’in dökümantasyonunda bununla ilgili detaylı bir tablo mevcut. İsterseniz Türkçe olarak laravel.gen.trde de aynı tabloya ulaşabilirsiniz.
İlk adım olarak routes.php
de tarifler
urlini oluşturmuştum. Şimdi kaynaklarım üzerinde işlemler için, silme-ekleme-güncelleme vs., TariflerController
altında gerekli metodları oluşturmam gerekli. Mesela
localhost/tarifler
için tüm tarifleri listeleyecek,localhost/tarifler/ekle
için yeni bir tarif oluşturmak için gerekli formu sunacak,localhost/tarifler/spagetti/guncelle
için spagetti tarifini güncelleyecekvb. metodları yazmam gerek. Bu kodları tek tek elimle yazacağım gibi Laravel’in "artisan"
aracını kullanabilirim. Artisan, Laravel’in kök dizininde bulunuyor. Artisan otomatik olarak bizim için TariflerController dosyasını oluşturup, dökümantasyonda belirtilen fonksiyonları ekleyecektir.
Bunu gerçekleştirmek için PowerShell’i açıp Laravel’i kurduğumuz dizine gitmemiz lazım. Sonrasında şu kodu yazarak işlemi tamamlıyoruz:
php artisan controller:make TariflerController
İşlemi doğru şekilde gerçekleştirirseniz “Controller created succesfully!” mesajını alacaksınız. Ve app/controllers
dizininde TariflerController.php
dosyası oluşturulup içinde gerekli metodların hazırlandığını göreceksiniz. Aynen bunun gibi:
<?php class TariflerController extends \BaseController { /** * Display a listing of the resource. * * @return Response */ public function index() { // } /** * Show the form for creating a new resource. * * @return Response */ public function create() { // } /** * Store a newly created resource in storage. * * @return Response */ public function store() { // } /** * Display the specified resource. * * @param int $id * @return Response */ public function show($id) { // } /** * Show the form for editing the specified resource. * * @param int $id * @return Response */ public function edit($id) { // } /** * Update the specified resource in storage. * * @param int $id * @return Response */ public function update($id) { // } /** * Remove the specified resource from storage. * * @param int $id * @return Response */ public function destroy($id) { // } }
Yukarıda bizim için otomatik olarak eklenen metodların ne işe yaradığını daha iyi anlamak dökümantasyon sayfasındaki tabloyu incelebilirsiniz. Açıklayıcı olması için yemek tarifleri sitemiz üzerinden birkaç örnek veriyorum:
GET
eylemi ile localhost/tarifler
urli çalışırsa index
metodu çalışacak.GET
eylemi ile localhost/tarifler/create
urli çalışırsa create
metodu çalışacak.POST
eylemi ile localhost/tarifler
urli çalışırsa store
metodu çalışacak.GET
eylemi ile localhost/spagetti
urli çalışırsa show
metodu çalışacak.Bu şekilde diğer HTTP eylemlerinde controller dosyasında çalışacak metodları çözebiliriz. Şimdi TariflerController
dosyamızda HTTP eylemlerine karşılık gerçekleştirmek istediğimiz kodları nasıl düzenleyeceğimizi öğrenelim:
İlk olarak yeni bir tarif eklemek istediğimizde ne yapacağımıza bakalım. Bunun için localhost/tarifler/create
url’ini kullanabiliriz. Bu durumda TariflerController
içindeki create
metodunu düzenlememiz gerek. Bu metodun yeni tarif ekleme için gerekli olan formu getirdiğini varsayalım.
TariflerController.php:
public function create() { return "Yeni tarif ekleme için form varmış gibi..."; }
Eğer şimdi localhost/tarifler/create
adresine gidersek bu mesaj bize döndürülecektir.
Eğer spagetti tarifini düzenlemek istersek localhost/tarifler/spagetti/edit
urlini kullanacağız. Bu durumda TariflerController.php
içindeki edit
metodunu düzenlememiz gerekli. edit
metodu bir $id
parametresine ihtiyaç duyuyor. localhost/tarifler/spagetti/edit
urlindeki spagetti
bizim id miz olacaktır.
public function edit($id) { return $id. "için düzenleme formu varmış gibi..."; }
localhost/tarifler/spagetti/edit
url ine gidersek yukarıdaki mesaj bizi karşılayacaktır. $id
yerine spagetti
yazacak.
Son olarak update
metodunu düzenleyelim. update
metodu da bir $id
parametresi alıyor ve PUT
eylemi ile çalışıyor. Yani verileri güncelleyip gönderdiğimiz formun metodu PUT
olmalı. Bunun için PUT
metoduyla çalışan basit bir form hazırlıyorum:
{{Form::open( array("url" => "tarifler/spagetti", "method" => "PUT") )}} {{Form::label("tarif", "Tarif")}} {{Form::text("tarif")}} {{Form::submit("Güncelle")}} {{Form::close()}}
Butona tıkladığım zaman, tarifler/spagetti
de PUT
eylemi gerçekleşecek. Yani TariflerController
içindeki update
metodunu düzenlemem lazım. $id
olarak spagetti
gelecek.
public function update($id) { return $id. " güncellendi"; }
Evet, bir faydalı konunun daha sonuna geldik. Laravel’in üç tipteki controller yapısını öğrendim. Böylece MVC yapısının View ve Controller katmanlarını az buçuk öğrenmiş oldum. Ayrıca REST ve RESTful web uygulamalarına da giriş yaptım.
Sıradaki konum Model katmanı üzerine olacak ve ileri veritabanı işlemlerini öğreneceğim:
Hatırlatma1: Laravel öğrenmek için bu linkteki eğitimi takip ediyorum ve öğrendiklerimi burada paylaşıyorum.Buraya tıklayarak eğitimin anasayfasına ulaşabilir ve kaynak kodlarını indirebilirsiniz.
Hatırlatma2: Lütfen eksik,hatalı ya da düzeltilmesi gereken bir şey farkederseniz bana bildirin.
Celery ile alakalı "best practice"leri ve faydalı araçları bir araya getiren güzel bir checklist'e denk…
Diziler en temel ve sık kullandığımız araçlardan... Kod yazarken işimizi kolaylaştıracak, daha temiz kod yazmamızı…
listve tuple bilginizi test etmek ister misiniz? realpython.com da keşfettiğim ve Türkçe'ye çevirdiğim mini teste…
Rehberlik sağlaması ve bilgi tazelemesi açısından faydalı olduğunu düşündüğüm bir Toptal blog paylaşımınıTürkçe'ye çevirdim.Devamını okuyunBilmeniz…
Angular componentlerine console üzerinden hızlıca erişmek için kullanılan bir teknik. Unutmamak için kendime not düşüyorum.Devamını…
Geçtiğimiz günlerde keşfettiğim ve oldukça da hoşuma giden repoyu paylaşmak istiyorum: lydiahallie/javascript-questions Genel olarak temel…