Burhan T. 4 dakikalık okuma
June 15, 2017

PHP’de Interface hadisesine derinden bakış

Burada bahsettiğim 3N tekniği ile PHP’de Interface meselesini ele alacağım. Amacım farklı bir üslübla konunun daha iyi anlaşılmasını sağlamak.

Şimdi 3N sorularına cevap verelim:

  1. Interface nedir ?
  2. PHP’de neden Interface’e ihtiyaç duyarız ve neden dile girmiştir ?
  3. PHP’de interface nasıl kullanılır ?

1. PHP’DE INTERFACE NEDİR ?

Interface’in Türkçe karşılığı arayüz demektir. Interface içerisine sadece metodlarımızın isimlerini parametreleriyle yazarız. Bu kadar !

Örnek :

Interface Database  
    {  
        public function createdb($dbname,$host,$username,$password);  
        public function getdata($rawsql);  
        public function deldata($table,$record,$where);  
       //...
    }  

2. PHP’DE NEDEN INTERFACE’E İHTİYAÇ DUYARIZ VE NEDEN DİLE GİRMİŞTİR ?

Büyük çapta ve ekiple geliştirilen projelerde belli standartların takip edilmesi çok önemlidir. Mesela bir projede veritabanı için birden fazla adaptör kullanacağız. Mysql, MSsql, InterBase etc. Bu tür durumlarda tüm sınıfları hazırladığımız interface (arayüz) üzerinden oluşturarak herkesin belirlenen kalıpta kod yazması sağlanabilinir.

3. PHP’DE İNTERFACE NASIL KULLANILIR ?

İlk başta interface anahtar kelimesini kullanarak arayüzümüzdeki metod isimlerini ve parametrelerini belirleyelim. Şöyle:

Interface Database  
    {  
        public function createdb($dbname,$host,$username,$password); 
        public function getdata($rawsql);  
        public function deldata($table,$record,$where);  
    }  

Sonra bu arayüzlerdeki metodları kodlamaya geçelim. Bunun için bir sınıf yazacağız ve bu sınıfı implement anahtar kelimesini kullanarak interface’den referans göstereceğiz. Şöyle:

Class MSSQL_adaptor implements Database   
    {  
        public function createdb($dbname,$host,$username,$password);  
        {
          // kodları yazıyoruz.
        } 

        public function getdata($rawsql);  
       {
          // kodları yazıyoruz.
         }

      public function deldata($table,$record,$where);  
        {
           // kodları yazıyoruz.
         }

    } 

Burada dikkat etmemiz gereken şu: Interface’te tanımladığımız metod isimleri ve parametreleri, virgülüne kadar hiç değiştirilmeden implement ettiğimiz class içinde de kullanılarak işlevleri kodlanıyor. Eğer interface içinde tanımlanmış bir metod implement edilen sınıf içerisinde kodlaması yapılmamışsa php fatal error vererek çalışmayı durdurur.

Interface içindeki tüm metodlar implement ettiğimiz sınıf içerisinde kodlanıp işlevleri yazıldıysa sorun olmaz. Ayrıca sınıf içinde interface’de olmayan başka metodlar da yazılabilir. Bunda bir mahsur yoktur. Şöyle:

interface IUser
{
  function getName();

}

class User implements IUser
{
  public  function Load( $id )  // interface içinde tanımlanmamış ama sınıfımız içerisinde kullanabiliriz.
  {
        return new User( $id );
  }

  public  function Create( ) //interface içinde tanımlanmamış ama sınıfımız içerisinde kullanabiliriz.
  {
        return new User( null );
  }


  public function getName()
  {
    return "Jack";
  }


}

Bundan başka çoklu sayıda genişletilebilir interface’ler oluşturulabilir. Şöyle:

interface a
{
public function foo();
}

interface b
{
public function bar();
}

interface c extends a, b
{
public function baz();
}

class d implements c
{
public function foo()
{
}

public function bar()
{
}

public function baz()
{
}
}

Yukarıdada bahsettiğim gibi Interface meselesinde amaç, ekiple geliştirilen projelerde belli standartların takip edilmesini bu yolla kolaylaştırmak.

Şimdi Interface’lerin özelliklerinden bahsedelim:

  • Interface’ler sihirbaz methodlar barındıramaz. (__construct, __clone methodlarından bahsediyorum). Ama implement eden class içinde kullanılabilir. Aşağıdaki örneği inceleyin:
interface Comparable
{
      function compare(self $compare);
}

// which is then implemented

class String implements Comparable
{
    private $string;
    function __construct($string)
    {$this->string = $string;}
    function compare(self $compare)
    {return $this->string == $compare->string;}
}

class Integer implements Comparable
{
    private $integer;
    function __construct($int)
    {$this->integer = $int;}
    function compare(self $compare)
    {return $this->integer == $compare->integer;}
}


$first_int = new Integer(3);
$second_int = new Integer(3);
$first_string = new String("foo");
$second_string = new String("bar");

var_dump($first_int->compare($second_int)); // bool(true)
var_dump($first_string->compare($second_string)); // bool(false)
var_dump($first_string->compare($second_int)); // Fatal Error
  • Interface ile çoklu kalıtım yapabilirsiniz (örn:
Class MSSQL_adaptor implements Database, Security,Backup  
  • Interface içerisinde tanımlanacak bütün methodlar public olmak zorundadır.
  • Interface içerisinde değişken tanımlayamayız. Sadece sabit tanımlayabiliriz. Şöyle:
interface deneme {
public $degisken1='bu bir degisken.'; // çalışmayacak. 
const sabit='bu bir sabit.' // çalışacak.
}

Şimdi Interface’lerin sınırını zorlayarak daha ileri şeyler yapmaya çalışalım:

INTERFACE VE SABITLER:

Interface içinde const anahtar kelimesi ile sabitlerimizi tanımlayarak bunları direkt kodlarımızda aşağıdaki örnek gibi kullanabiliriz. Yani sabitleri illa ki kullanmak için bir sınıf ile implement etmek gerekmez.

interface sabit
{
    const b = 'Interface constant';
}

// Direkt çalışacak
echo sabit::b;

INTERFACE’IN EN BÜYÜK AVANTAJINI AŞAĞIDAKİ ÖRNEKLE GÖSTERELİM

Aşağıdaki örnek çok önemli. Yazılan bir interface konteynır gibi kullanılıyor ve o referans alınarak türetilen bir sınıfta nasıl başka sınıfların geçirildiği son derece net bir şekilde anlatılıyor:

interface IDoSomething {
    public  function doSomething();
}

class One implements IDoSomething {
    public  function doSomething() {
        echo "One is doing something\n";
    }
}

class Two extends One {
    public  function doSomething() {
        echo "Two is doing something\n";
    }
}

function example(IDoSomething $doer) {
    $doer->doSomething();
}

example(new One()); // One is doing something
example(new Two()); // Two is doing something

Etiketler: