MVC Uygulaması İçin İlk Adımlar: App Sınıfı

2 Aralık 2016 Cuma günü PHP başlığında

MVC Uygulaması İçin İlk Adımlar: App Sınıfı

İkinci yazıdan merhaba arkadaşlar. Bu yazıda çalışmalara başlayıp ortaya güzel şeyler çıkaracağız. Evvela MVC uygulamasında kendimize uygun bir dizin yapısı belirlememiz gerekiyor. Bizim yapacağımız sistem şu şekilde olacak:

/app
  /controllers
    defaultController.php
    postController.php
  /core
    app.php
    controller.php
    model.php
    view.php
  /models
    post.php
  /views
    -görünüm dosyaları-
index.php

Evvela, /core dizinindeki app.php dosyası ile başlıyoruz. app sınıfı, bizim temel işlemlerimizi yapacak olan sınıftır. Kabaca anlatmak gerekirse bir kullanıcı siteye girdiği vakit ilk olarak app sınıfından geçecek ve kullanıcının ne istediğini app sınıfında yapacağımız işlemlerle anlayıp yönlendireceğiz. app sınıfı ile controller dosyalarını tetikleyecek, controller dosyaları ile model ve view katmanlarını kullanacağız.

/app/core/app.php:

class app
{
  /**
   * Sınıf içerisinde tutulacak değerler
   * __construct metodu ile belirleyip
   * run metodu ile kullanacağız
   */
  public $controller, $action, $params;

  /**
   * Controller ve Action'ı belirleyen başlatıcı metod
   */
  public function __construct()
  {
    /**
     * Eğer url sorgusu varsa, başındaki ve
     * sonundaki / işaretlerini siliyoruz
     * yoksa geçerli olarak default/index
     */
    $url = isset($_GET['url']) && !empty($_GET['url']) ? trim($_GET['url'], '/') : 'default/index';

    /**
     * URL dizgesini / karakterleriyle bölüyoruz
     * Böylelikle her bölüme ulaşabileceğiz
     */
    $url = explode('/', $url);

    /**
     * Controller ve Action'ı belirliyoruz
     * Eğer $url[0] varsa onu $url[0].'Controller' yani $url[0]'ın default olduğunu varsayalım
     * indexController olacaktır, eğer yoksa defaultController olarak ayarla dedik
     * Aynı işlemi action için de yapıyoruz. Action $url[1]'de yer alıyor
     */
    $this->controller = isset($url[0]) ? $url[0].'Controller' : 'defaultController';
    $this->action = isset($url[1]) ? $url[1].'Action' : 'indexAction';

    /**
     * array_shift fonksiyonu, dizedeki ilk elemanı siler/kaldırır
     */
    array_shift($url);
    array_shift($url);

    /**
     * $url[0] ve $url[1]'i aldık, gerisi parametre. 
     * Yani default/index/1/2/3'ün 1/2/3 olan yeri. 
     */
    $this->params = $url;
  }
}

Dikkat edilmesi gereken nokta $_GET['url'] kodunu kullanarak neler yaptığımız. Öncelikle varlığını sorguluyor varsa sağ ve solunda bulunan / karakterlerini trim fonksiyonu ile siliyoruz. Eğer yoksa, geçerli olarak hangi controller’ı alacağını belirliyoruz.

Uygulamada geçerli controller katmanı defaultController’dır. Geçerli aksiyon ise indexAction’dır. Aldığımız URL’i explode ile parçalara ayırıyoruz ve sınıf içerisinde bulunan değişkenlere veriyoruz. Çünkü daha sonrasında bunları run() metodunda kullanacağız.

Şimdi gelelim run() metoduna. Burada URL barından aldığımız değerlere göre hareket edip controller dosyalarını çağıracağız ve bunlara göre işlemler yapacağız. Haydi.

/app/core/app.php (devamı):

class app
{
  /**
   * Sınıf içerisinde tutulacak değerler
   * __construct metodu ile belirleyip
   * run metodu ile kullanacağız
   */
  public $controller, $action, $params;

  /**
   * Controller ve Action'ı belirleyen başlatıcı metod
   */
  public function __construct()
  {
    /**
     * Eğer url sorgusu varsa, başındaki ve
     * sonundaki / işaretlerini siliyoruz
     * yoksa geçerli olarak default/index
     */
    $url = isset($_GET['url']) && !empty($_GET['url']) ? 
      trim($_GET['url'], '/') : 'default/index';

    /**
     * URL dizgesini / karakterleriyle bölüyoruz
     * Böylelikle her bölüme ulaşabileceğiz
     */
    $url = explode('/', $url);

    /**
     * Controller ve Action'ı belirliyoruz
     * Eğer $url[0] varsa onu $url[0].'Controller' yani $url[0]'ın default olduğunu varsayalım
     * indexController olacaktır, eğer yoksa defaultController olarak ayarla dedik
     * Aynı işlemi action için de yapıyoruz. Action $url[1]'de yer alıyor
     */
    $this->controller = isset($url[0]) ? $url[0].'Controller' : 'defaultController';
    $this->action = isset($url[1]) ? $url[1].'Action' : 'indexAction';

    /**
     * array_shift fonksiyonu, dizedeki ilk elemanı siler/kaldırır
     */
    array_shift($url);
    array_shift($url);

    /**
     * $url[0] ve $url[1]'i aldık, gerisi parametre. 
     * Yani default/index/1/2/3'ün 1/2/3 olan yeri. 
     */
    $this->params = $url;
  }

  /**
   * Uygulamayı başlatır
   */
  public function run()
  {
    // Eğer Controller dosyası varsa $file değişkenini yol olarak belirle
    if (file_exists($file = CDIR."/{$this->controller}.php")) {
      // Dosyayı sistemimize dahil edelim
      require_once $file;
      // Eğer sınıf yaratılmışsa/varsa controller'ımızı çağıralım
      if (class_exists($this->controller)) {
        // controller'ı çağıralım:
        $controller = new $this->controller;
        // Eğer metod varsa ve yaratılmışsa
        if (method_exists($controller, $this->action)) {
          // call_user_func ile controller ve metodu çağırıyoruz
          call_user_func_array([$controller, $this->action], $this->params);
        // Eğer method yoksa programdan çık
        } else {
          exit("Metod mevcut değil: {$this->action}");
        }
      // Sınıf yoksa ve yaratılmamışsa programdan çık
      } else {
        exit("Sınıf mevcut değil: $this->controller");
      }
    // Controller dosyası yoksa programdan çık
    } else {
      exit("Controller dosyası mevcut değil: {$this->controller}.php");
    }
  }
}

__construct() metodunda topladığımız bilgilerle birkaç kontrol sağlayarak işe başlıyoruz. file_exists fonksiyonu ile dosyanın var olup olmadığını soruyoruz. Burada CDIR isimli bir sabit var, bunu daha sonra index.php’de Controller dizinini işaret eden sabit olarak ayarlayacağız. Controller varsa sayfayı dahil ediyoruz, sonra sınıf ve sonrasında ise metod kontrolü yapıyoruz. Eğer her şey yolundaysa temel noktaya geliyoruz. call_user_func_array() fonksiyonu ile daha önceden belirlenmiş olan controller, action ve parametreleri çağırıyoruz. Sonucunda sistemin yapı taşını oturtmuş oluyoruz.

Örnek call_user_func_array() Fonksiyonu Kullanımı

Bu fonksiyon oldukça iş gören bir fonksiyondur. Basit bir örnekle açıklayayım:

function printMessage($name)
{
  echo "Merhaba {$name}!";
}

call_user_func_array('printMessage', ['Durruti']);

Buradaki fonksiyonu printMessage('Durruti') şeklinde de yazdırabilirdik yalnız bazı spesifik durumlarda bunu kullanamıyoruz o yüzden bu fonksiyona ihtiyaç duyabiliyoruz. Sınıflarla ise, şu şekilde çalışıyor:

class Alert
{
  public function name($name)
  {
    return "Dikkat et {$name}!";
  }
}

echo call_user_func_array([new Alert, 'name'], ['Onur']);

Son örneğimizde ise, daha kolay anlaşılabilmesi adına uygulamada kullandığımıza yakın bir örnek vereceğim. Yalnız bu sadece ufak bir senaryo, bu şekilde kullanmıyoruz:

class postController
{
  public function getAction($id)
  {
   echo 'Gösterilecek gönderi ID: ' . $id;
  }
}

if ($_GET['controller'] === 'post' && $_GET['action'] === 'get') {
  call_user_func_array([new postController, 'getAction'], [5]);
}

Umarım aklınızda yer etmiştir. Bu konuyu biraz daha internette araştırarak yeni şeyler katabilirsiniz kendinize. Bu bölüm şimdilik bu kadar. Önümüzdeki yazıda, kullanıcının ilk karşılaşacağı index.php sayfasını işleyeceğiz.

Kolay gelsin.


Adım adım:

  1. Yeni Başlayanlar İçin PHP'de MVC
  2. MVC Uygulaması İçin İlk Adımlar: App Sınıfı (Şu an buradasınız)
  3. MVC’de Giriş Sayfası, Ayarlamalar ve İlk Controller
  4. Controller ve View Çekirdek Sınıflarını Oluşturmak
  5. Model Katmanı ve Veritabanı İşlemlerini Kolaylaştırmak
  6. Proje/Uygulamanın Deposu
  7. Uygulamanın bitmiş halini indirin

Yorumlar