Merhaba! Eğer PHP ile web geliştirme yapıyorsanız ve kodunuzu daha modüler, yeniden kullanılabilir ve yönetilebilir hale getirmek istiyorsanız, Nesne Yönelimli Programlama (OOP) tam size göre. PHP, başlangıçta prosedürel bir dil olsa da, PHP 5'ten itibaren güçlü OOP desteği sunuyor. Bu makalede, PHP'de OOP'nin temel kavramlarını, avantajlarını, temel bileşenlerini ve ileri düzey konularını uzun uzadıya ele alacağız. Yeni başlayanlar için adım adım örnekler vereceğiz, deneyimli geliştiriciler için ise en iyi pratikleri paylaşacağız. Makaleyi okuduktan sonra, kendi OOP tabanlı PHP projelerinizi oluşturmaya hazır olacaksınız. Daha fazla kaynak ve örnek için https://www.gulgec.tr adresini ziyaret edebilirsiniz.

OOP Nedir ve PHP'de Neden Kullanılır?

Nesne Yönelimli Programlama, yazılımı "nesneler" etrafında yapılandırma yaklaşımıdır. Her nesne, verileri (özellikler) ve bu verilerle ilgili işlemleri (metotlar) içerir. OOP'nin dört temel prensibi vardır: Encapsulation (Kapsülleme), Inheritance (Kalıtım), Polymorphism (Çok Biçimlilik) ve Abstraction (Soyutlama). Bunları ilerleyen bölümlerde detaylandıracağız.

PHP'de OOP kullanmanın avantajları:

  • Modülerlik: Kodunuzu sınıflar halinde organize ederek, bakımını kolaylaştırır.
  • Yeniden Kullanılabilirlik: Bir sınıfı birden fazla yerde kullanabilirsiniz.
  • Güvenlik: Verileri gizleyerek hataları önler.
  • Gerçek Dünya Modelleme: Nesneler, gerçek hayattaki varlıkları (örneğin, bir araba veya kullanıcı) temsil eder.
  • Büyük Projeler İçin Uygun: Laravel, Symfony gibi framework'ler OOP tabanlıdır.

PHP 4'te sınırlı OOP desteği vardı, ancak PHP 5 ile tam özellikler eklendi (nesneler, arayüzler, soyut sınıflar). PHP 7 ve 8'de performans iyileştirmeleri ve yeni özellikler (typed properties, attributes) geldi.

Temel Kavramlar: Sınıflar ve Nesneler

OOP'nin temel taşı sınıf (class) ve nesne (object)'dir. Sınıf, bir şablondur; nesne ise bu şablondan oluşturulan örneklerdir.

  • Sınıf Tanımlama: class anahtar kelimesiyle başlar.

    <?php
    class Araba {
    // Özellikler (properties)
    public $marka;
    public $model;
    public $yil;
    // Metot (method)
    public function bilgiVer() {
    echo "Bu araba {$this->marka} {$this->model} modelidir ve {$this->yil} yılındadır.";
    }
    }
    ?>
    Burada $this, nesnenin kendisine referans verir.
  • Nesne Oluşturma: new ile.

    <?php
    $benimArabam = new Araba();
    $benimArabam->marka = "Toyota";
    $benimArabam->model = "Corolla";
    $benimArabam->yil = 2020;
    $benimArabam->bilgiVer(); // Çıktı: Bu araba Toyota Corolla modelidir ve 2020 yılındadır.
    ?>
  • Yapıcı Metot (Constructor): Nesne oluşturulduğunda otomatik çalışır. __construct() ile tanımlanır.

    <?php
    class Araba {
    public $marka;
    public $model;
    public $yil;
    public function __construct($marka, $model, $yil) {
    $this->marka = $marka;
    $this->model = $model;
    $this->yil = $yil;
    }
    public function bilgiVer() {
    echo "Bu araba {$this->marka} {$this->model} modelidir ve {$this->yil} yılındadır.";
    }
    }
    $benimArabam = new Araba("Toyota", "Corolla", 2020);
    $benimArabam->bilgiVer();
    ?>
  • Yıkıcı Metot (Destructor): Nesne yok edildiğinde çalışır. __destruct() ile.

    <?php
    class Araba {
    // ... diğer kodlar ...
    public function __destruct() {
    echo "Araba nesnesi yok edildi.";
    }
    }
    ?>

Erişim Belirleyiciler: Public, Protected, Private

OOP'de verilerin ve metotların erişimini kontrol etmek önemlidir.

  • Public: Her yerden erişilebilir.
  • Protected: Sadece sınıf ve alt sınıflardan erişilebilir.
  • Private: Sadece sınıf içinden erişilebilir.

Örnek:


<?php
class Kullanici {
public $isim; // Her yerden erişim
protected $yas; // Sınıf ve alt sınıflar
private $sifre; // Sadece sınıf içi
public function __construct($isim, $yas, $sifre) {
$this->isim = $isim;
$this->yas = $yas;
$this->sifre = $sifre;
}
public function bilgileriGoster() {
echo "İsim: $this->isim, Yaş: $this->yas"; // Sifre'yi göstermiyoruz
}
}
$kullanici = new Kullanici("Ahmet", 30, "12345");
echo $kullanici->isim; // Erişilebilir
// echo $kullanici->yas; // Hata: Protected
// echo $kullanici->sifre; // Hata: Private
?>

Bu, encapsulation'ı sağlar: Verileri gizleyerek doğrudan erişimi engeller.

Kalıtım (Inheritance): Üst Sınıflardan Miras Alma

Kalıtım, bir sınıfın başka bir sınıftan özellik ve metotları miras almasıdır. extends ile yapılır.

  • Temel Örnek:

    <?php
    class Arac {
    public $tekerSayisi = 4;
    public function hareketEt() {
    echo "Araç hareket ediyor.";
    }
    }
    class Araba extends Arac {
    public $marka;
    public function __construct($marka) {
    $this->marka = $marka;
    }
    public function bilgiVer() {
    echo "Bu {$this->marka} arabası {$this->tekerSayisi} tekerleğe sahiptir.";
    }
    }
    $benimArabam = new Araba("BMW");
    $benimArabam->bilgiVer(); // Miras alınan özellik
    $benimArabam->hareketEt(); // Miras alınan metot
    ?>
  • Metot Ezme (Overriding): Alt sınıf, üst sınıfın metotunu yeniden tanımlayabilir.

    <?php
    class Arac {
    public function hareketEt() {
    echo "Araç yavaş hareket ediyor.";
    }
    }
    class Araba extends Arac {
    public function hareketEt() {
    echo "Araba hızlı hareket ediyor.";
    }
    }
    $araba = new Araba();
    $araba->hareketEt(); // Araba hızlı hareket ediyor.
    ?>
  • Parent ve Super: Üst sınıf metotlarını çağırmak için parent:: kullanılır.

    <?php
    class Araba extends Arac {
    public function hareketEt() {
    parent::hareketEt(); // Üst sınıfı çağır
    echo " Ama araba daha hızlı!";
    }
    }
    ?>

Çok Biçimlilik (Polymorphism): Farklı Nesnelerin Aynı Arayüzü Kullanması

Polymorphism, farklı sınıfların aynı metot isimlerini kullanarak farklı davranışlar sergilemesidir. Arayüzler (interfaces) ve soyut sınıflar (abstract classes) ile sağlanır.

  • Arayüz (Interface): Metot imzalarını tanımlar, 구현 etmez.

    <?php
    interface SesCikar {
    public function sesVer();
    }
    class Kopek implements SesCikar {
    public function sesVer() {
    echo "Hav hav!";
    }
    }
    class Kedi implements SesCikar {
    public function sesVer() {
    echo "Miyav!";
    }
    }
    function hayvanSesiniCikar(SesCikar $hayvan) {
    $hayvan->sesVer();
    }
    $kopek = new Kopek();
    $kedi = new Kedi();
    hayvanSesiniCikar($kopek); // Hav hav!
    hayvanSesiniCikar($kedi); // Miyav!
    ?>
  • Soyut Sınıf (Abstract Class): Kısmen uygulanmış sınıf, alt sınıflar tarafından genişletilir.

    <?php
    abstract class Sekil {
    abstract public function alanHesapla(); // Uygulanmaz
    public function bilgiVer() {
    echo "Bu bir şekil.";
    }
    }
    class Dikdortgen extends Sekil {
    private $uzunluk;
    private $genislik;
    public function __construct($uzunluk, $genislik) {
    $this->uzunluk = $uzunluk;
    $this->genislik = $genislik;
    }
    public function alanHesapla() {
    return $this->uzunluk * $this->genislik;
    }
    }
    $dikdortgen = new Dikdortgen(5, 3);
    echo $dikdortgen->alanHesapla(); // 15
    ?>

Soyutlama (Abstraction) ve Kapsülleme (Encapsulation)

  • Abstraction: Gereksiz detayları gizler, sadece gerekli arayüzü sunar. Soyut sınıflar ve arayüzlerle yapılır.
  • Encapsulation: Verileri ve metotları sınıf içinde tutar, erişimi kısıtlar. Getter ve setter metotları kullanılır.

    <?php
    class BankaHesabi {
    private $bakiye = 0;
    public function paraYatir($miktar) {
    $this->bakiye += $miktar;
    }
    public function paraCek($miktar) {
    if ($miktar <= $this->bakiye) {
    $this->bakiye -= $miktar;
    } else {
    echo "Yetersiz bakiye!";
    }
    }
    public function bakiyeGoster() {
    return $this->bakiye;
    }
    }
    $hesap = new BankaHesabi();
    $hesap->paraYatir(1000);
    $hesap->paraCek(500);
    echo $hesap->bakiyeGoster(); // 500
    // $hesap->bakiye = 10000; // Hata: Private
    ?>

İleri Düzey OOP Konuları

  • Traits: Yeniden kullanılabilir kod blokları, birden fazla sınıfa eklenebilir.

    <?php
    trait Loglama {
    public function logYaz($mesaj) {
    echo "Log: $mesaj";
    }
    }
    class Kullanici {
    use Loglama;
    public function girisYap() {
    $this->logYaz("Kullanıcı giriş yaptı.");
    }
    }
    $kullanici = new Kullanici();
    $kullanici->girisYap();
    ?>
  • Typed Properties (PHP 7.4+): Özelliklere tip belirtme.

    <?php
    class Kullanici {
    public string $isim;
    public int $yas;
    }
    ?>
  • Attributes (PHP 8+): Meta veri ekleme.

    <?php
    #[Attribute]
    class Deprecated {}
    ?>
  • Static Özellikler ve Metotlar: Sınıfa ait, nesne olmadan erişilir.

    <?php
    class Sayac {
    public static $sayi = 0;
    public static function arttir() {
    self::$sayi++;
    }
    }
    Sayac::arttir();
    echo Sayac::$sayi; // 1
    ?>
  • Magic Methods: __get(), __set(), __call() gibi özel metotlar.

    <?php
    class Dinamik {
    public function __call($isim, $argumanlar) {
    echo "Çağrılan metot: $isim";
    }
    }
    $nesne = new Dinamik();
    $nesne->bilinmeyenMetot(); // Çağrılan metot: bilinmeyenMetot
    ?>

OOP En İyi Pratikleri ve Hatalar

  • SOLID Prensipleri: Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, Dependency Inversion.
  • Hatalar: Aşırı kalıtım (inheritance hell), global değişken kullanımı, encapsulation'ı ihmal etmek.
  • Performans: OOP prosedürelin biraz daha yavaş olabilir, ama modern PHP'de fark azaldı.
  • Güvenlik: Girişleri doğrula, private kullan.

Örnek Proje: Basit Bir Kullanıcı Sistemi


<?php
abstract class KullaniciRol {
abstract public function yetkileriGoster();
}
interface GirisYapabilir {
public function girisYap($sifre);
}
class Kullanici implements GirisYapabilir {
private $isim;
private $sifreHash;
protected $rol;
public function __construct($isim, $sifre) {
$this->isim = $isim;
$this->sifreHash = password_hash($sifre, PASSWORD_DEFAULT);
}
public function girisYap($sifre) {
return password_verify($sifre, $this->sifreHash);
}
public function rolAta(KullaniciRol $rol) {
$this->rol = $rol;
}
public function yetkileriGoster() {
if ($this->rol) {
$this->rol->yetkileriGoster();
}
}
}
class Admin extends KullaniciRol {
public function yetkileriGoster() {
echo "Admin yetkileri: Her şeyi yönetebilir.";
}
}
class Misafir extends KullaniciRol {
public function yetkileriGoster() {
echo "Misafir yetkileri: Sadece görüntüleyebilir.";
}
}
$kullanici = new Kullanici("AdminUser", "gizlisifre");
$kullanici->rolAta(new Admin());
if ($kullanici->girisYap("gizlisifre")) {
$kullanici->yetkileriGoster(); // Admin yetkileri...
}
?>

Bu örnek, OOP'nin gücünü gösterir: Modüler, genişletilebilir bir sistem.

Sonuç

PHP'de OOP, kodunuzu profesyonel seviyeye taşır. Başlangıçta karmaşık gelebilir, ama pratikle alışacaksınız. Çerçeveler (Laravel) öğrenerek uygulayın. Daha detaylı örnekler için https://www.gulgec.tr sitesini inceleyin. Sorularınız olursa yorum bırakın!