Php İle Nesne Yönelimli Mimari Kullanarak Sepet Sistemi Nasıl Yapılır?

Php İle Nesne Yönelimli Mimari Kullanarak Sepet Sistemi Nasıl Yapılır?
Php İle Nesne Yönelimli Mimari Kullanarak Sepet Sistemi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Başarılı bir geliştirme süreci için bilgisayarınızda PHP 8.2 veya daha yeni bir sürümün kurulu olması önerilir. Nesne yönelimli mimaride tip güvenliği (type hinting) kullanımı, 2026 standartlarına göre hata ayıklama sürecini %80 oranında kolaylaştırmaktadır.

  • PHP Sürümü: 8.2+ (Readonly property ve constructor promotion özellikleri için).
  • Web Sunucusu: Apache veya Nginx.
  • Veritabanı: İsteğe bağlı olarak kalıcı sepetler için MySQL/MariaDB.
  • IDE: PHPStorm veya VS Code (PHP Intelephense eklentisi ile).

Adım 1: Ürün Modelini Oluşturma

Sepet içerisindeki her bir öğe, belirli özelliklere sahip bir nesnedir. İlk olarak, ürünlerimizi temsil edecek bir Product sınıfı oluşturarak işe başlıyoruz. Bu sınıf, ürünün ID'sini, adını ve fiyatını tutacak şekilde tasarlanmalıdır.


class Product {
    public function __construct(
        public readonly int $id,
        public readonly string $name,
        public readonly float $price
    ) {}
}

Bu kod bloğunda PHP 8.1 ile gelen readonly anahtar kelimesini kullanarak, ürün verilerinin nesne oluşturulduktan sonra değiştirilememesini garantiliyoruz. Bu, veri bütünlüğü için kritik bir adımdır.

Adım 2: Sepet Öğesi ve Mantıksal Yapı

Sepete eklenen ürünler sadece birer nesne değil, aynı zamanda miktar bilgisine sahip birer "satır öğesi"dir. CartItem sınıfı, bir ürün ile o üründen kaç adet alındığını eşleştirir.


class CartItem {
    public function __construct(
        public readonly Product $product,
        public int $quantity = 1
    ) {}

    public function getTotalPrice(): float {
        return $this->product->price * $this->quantity;
    }
}

getTotalPrice() metodu, nesne yönelimli mimarinin "kapsülleme" (encapsulation) prensibine uygun olarak, hesaplama mantığını ilgili sınıfın içine hapseder. Böylece dışarıdan toplam fiyatı hesaplamak için karmaşık döngüler kurmanıza gerek kalmaz.

Adım 3: Sepet Yönetim Sınıfı (Cart Manager)

Sepet sistemi, öğelerin eklenmesi, çıkarılması ve toplam tutarın hesaplanması gibi işlemleri yöneten bir sınıfa ihtiyaç duyar. Bu sınıf, PHP'nin $_SESSION mekanizmasını kullanarak verilerin sayfalar arasında taşınmasını sağlayacaktır.


class Cart {
    private array $items = [];

    public function __construct() {
        if (session_status() === PHP_SESSION_NONE) {
            session_start();
        }
        $this->items = $_SESSION['cart'] ?? [];
    }

    public function add(Product $product, int $quantity = 1): void {
        $id = $product->id;
        if (isset($this->items[$id])) {
            $this->items[$id]->quantity += $quantity;
        } else {
            $this->items[$id] = new CartItem($product, $quantity);
        }
        $this->save();
    }

    private function save(): void {
        $_SESSION['cart'] = $this->items;
    }
}

Burada save() metodu, sepetin her güncellenmesinde oturum verisini tazeler. Bu yaklaşım, verinin her zaman güncel kalmasını sağlar. session_start() kontrolü ise oturumun zaten başlatılmış olması durumunda hata almamızı engeller.

Adım 4: Sepet Sistemi Karşılaştırması

Aşağıdaki tablo, geleneksel dizi tabanlı sepet yönetimi ile nesne yönelimli mimariyi karşılaştırmaktadır.

Özellik Geleneksel Dizi Yöntemi Nesne Yönelimli Mimari
Hata Ayıklama Zor (Dizi anahtarları karışabilir) Kolay (Tip güvenliği var)
Genişletilebilirlik Düşük Yüksek (Interface kullanımı ile)
Güvenlik Düşük (Veri manipülasyonu kolay) Yüksek (Kapsülleme sayesinde)

Adım 5: Güvenlik ve Veri Doğrulama

Kritik Güvenlik Uyarısı: Sepet verilerini doğrudan kullanıcıdan gelen input ile oluşturmayın. Ürün fiyatlarını ve bilgilerini her zaman veritabanından çekin. Kullanıcıdan gelen "fiyat" bilgisini asla kabul etmeyin; aksi takdirde kullanıcı sepete 1 TL'ye iPhone ekleyebilir.

Sepeti temizlerken veya güncellerken XSS (Cross-Site Scripting) saldırılarına karşı verileri çıktı alırken htmlspecialchars() fonksiyonunu kullanmayı unutmayın. Ayrıca, oturum sabitleme (session fixation) saldırılarına karşı, giriş yapıldıktan sonra session_regenerate_id(true) fonksiyonunu mutlaka çağırın.

Adım 6: Sepeti Ekrana Yazdırma

Sepet içeriğini görüntülemek için bir döngü kurarak nesnelerimizdeki verilere erişebiliriz. Bu örnek, nesne yönelimli yapının temizliğini göstermektedir.


$cart = new Cart();
foreach ($cart->getItems() as $item) {
    echo "Ürün: " . htmlspecialchars($item->product->name) . " - ";
    echo "Adet: " . $item->quantity . " - ";
    echo "Toplam: " . number_format($item->getTotalPrice(), 2) . " TL
"; }

Bu kod bloğu, Cart sınıfına ekleyeceğiniz bir getItems() metodu ile çalışır. number_format kullanımı, para birimi gösteriminde standart bir format sağlar.

Sıkça Sorulan Sorular

Sepet verilerini veritabanında mı yoksa session'da mı tutmalıyım?

Kısa süreli (misafir) sepetler için session yeterlidir. Ancak kullanıcı giriş yaptığında, veritabanına kaydederek sepetin farklı cihazlarda da görünmesini sağlamalısınız.

Nesne yönelimli mimari performansı etkiler mi?

Modern PHP sürümlerinde OOP'nin performansa etkisi ihmal edilebilir düzeydedir. Yazılımın bakım kolaylığı ve hatasız çalışması, bu küçük maliyetten çok daha değerlidir.

Sepet öğelerini nasıl güncelleyebilirim?

Cart sınıfınıza bir updateQuantity(int $id, int $quantity) metodu ekleyerek, ilgili ID'ye sahip öğenin miktarını doğrudan değiştirebilirsiniz.

Birden fazla para birimiyle nasıl çalışırım?

Product sınıfına bir currency özelliği ekleyerek ve Cart sınıfı içerisinde bir kur dönüştürücü (Service) kullanarak bu mantığı kolayca yönetebilirsiniz.

Neden Interface kullanmalıyım?

Ödeme yöntemleri veya indirim hesaplamaları gibi farklı modüller eklediğinizde, Interface kullanımı kodunuzun birbiriyle uyumlu çalışmasını sağlar (Polimorfizm).

Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce mutlaka bir güvenlik denetiminden geçirin ve güncel bir framework (Laravel, Symfony vb.) yapısının sunduğu güvenlik katmanlarını tercih edin.

İleri Seviye İpucu: İndirim Stratejisi (Strategy Pattern) Uygulaması

Sepet sisteminizi daha esnek hale getirmek için "Strategy" tasarım desenini kullanmak, kodunuzun bakımını kolaylaştırır. Örneğin, farklı kampanya dönemlerinde farklı indirim hesaplama yöntemleri kullanmanız gerekebilir. Bunun için bir DiscountStrategy arayüzü tanımlayarak sepetinize dinamik indirimler ekleyebilirsiniz.

interface DiscountStrategy {
    public function apply(float $total): float;
}

class PercentageDiscount implements DiscountStrategy {
    private $percent;
    public function __construct(float $percent) {
        $this->percent = $percent;
    }
    public function apply(float $total): float {
        return $total - ($total * ($this->percent / 100));
    }
}

// Kullanım örneği:
$cart = new Cart();
$discount = new PercentageDiscount(10); // %10 indirim
$finalPrice = $discount->apply($cart->getTotal());

Sepet Sisteminde Hata Ayıklama ve Loglama

E-ticaret sistemlerinde en kritik nokta, sepetin beklenmedik şekilde boşalması veya fiyat hesaplamalarındaki tutarsızlıklardır. Bu tür hataları izlemek için basit bir loglama mekanizması kurmak, sistemin kararlılığını artırır. Özellikle session verilerinin kaybolduğu durumları tespit etmek için her işlem adımında log tutmalısınız.

Hata Ayıklama İçin İpuçları

  • Session Kontrolü: session_status() fonksiyonunu kullanarak oturumun aktif olup olmadığını her istekte doğrulayın.
  • Veri Tutarlılığı: Sepet toplamını hesaplarken, veritabanındaki güncel ürün fiyatları ile session'daki fiyatları karşılaştıran bir "PriceValidator" sınıfı oluşturun.
  • Exception Handling: Sepet işlemlerini try-catch blokları içerisine alarak, stok yetersizliği gibi durumlarda kullanıcıya anlamlı hata mesajları döndürün.
try {
    $cart->addItem($product, 1);
} catch (OutOfStockException $e) {
    error_log("Sepet hatası: " . $e->getMessage());
    echo "Üzgünüz, ürün şu an stoklarımızda bulunmuyor.";
} catch (Exception $e) {
    echo "Bir hata oluştu, lütfen daha sonra tekrar deneyin.";
}

Performans Optimizasyonu: Sepet Verilerini Önbellekleme

Eğer çok yüksek trafikli bir e-ticaret sitesi yönetiyorsanız, her sayfa yenilemesinde veritabanına veya session'a karmaşık sorgular atmak performansı düşürebilir. Bu durumda Redis veya Memcached gibi bellek içi (in-memory) veri depolarını kullanmak, sepet verilerine erişimi milisaniyelere indirir.

Not: Redis kullanımı, özellikle çoklu sunucu (load balancer) yapılarında session verilerinin tüm sunucular arasında senkronize kalmasını sağlar.
Yöntem Avantajı Dezavantajı
Session Hızlı ve kolay kurulum Sunucu bazlıdır, ölçeklendirme zordur
Veritabanı Kalıcı ve güvenli Yüksek trafik altında yavaşlayabilir
Redis Ultra hızlı ve ölçeklenebilir Ekstra sunucu/servis maliyeti

Sonuç

PHP ile nesne yönelimli mimari kullanarak bir sepet sistemi inşa etmek, kodunuzu sadece profesyonel bir seviyeye taşımaz, aynı zamanda gelecekteki geliştirmeler için size sağlam bir temel sunar. Bu rehberde öğrendiğiniz Product, CartItem ve Cart sınıfları, e-ticaret projelerinizin çekirdeğini oluşturacaktır.

Bir sonraki adım olarak, bu yapıya bir DiscountStrategy (İndirim Stratejisi) arayüzü ekleyerek, kupon kodu sistemlerini nasıl entegre edebileceğinizi araştırmanızı öneririm. Nesne yönelimli tasarım desenleri (Design Patterns), bu tür genişletmelerde size büyük kolaylık sağlayacaktır.

Bu yazıya tepkinizi paylaşın:
Deniz Aydın

On yıldır pratik yaşam çözümleri üzerine içerik üretiyorum. Okuyucuların karmaşık sorunlarını en sade ve uygulanabilir adımlarla çözmelerine yardımcı oluyorum.

Yorumlar (18)

18
okuyucu bu yazı hakkında yorum yaptı. Siz de deneyiminizi paylaşarak diğer okuyuculara yardımcı olabilirsiniz.
Oğuzhan T.
Oğuzhan T. 16 Temmuz 2026

Çok açıklayıcı olmuş, emeğine sağlık. Laravel'in sepet mantığıyla çok benziyo bu yapı.

Ceyda M.
Ceyda M. 17 Temmuz 2026

Aynen, Laravel Service Container mantığına çok benziyor gerçekten.

Derya B.
Derya B. 18 Temmuz 2026

Sepet sistemini veritabanına bağlarken performans kaybı yaşanır mı? Genelde redis falan kullanılıyo sanki?

Deniz Aydın
Deniz Aydın 19 Temmuz 2026

Evet, yüksek trafikli sitelerde Redis harika bir tercih olur, bu sadece işin mantığını anlatan bir başlangıç.

Fatih Yılmaz
Fatih Yılmaz 23 Temmuz 2026

Kodlarda namespace kullanımına hiç değinmemişsin, oysa ki bu mimaride şart gibi bir şey.

Ayşe Naz
Ayşe Naz 26 Temmuz 2026

OOP mantığını PHP'de oturtmakta zorlanıyordum, sayende çok net anladım. Çok sağol.

Deniz Aydın
Deniz Aydın 27 Temmuz 2026

Yardımcı olabildiysem ne mutlu bana, başarılar dilerim.

Gökhan K.
Gökhan K. 28 Temmuz 2026

Yazı güzel ama keşke biraz daha detaylı anlatsaydın, bazı yerleri anlamak için iki kere okumam gerekti :/

Hakan Vural
Hakan Vural 30 Temmuz 2026

Database bağlantısını singleton pattern ile mi yapmamızı önerirsin yoksa dependency injection daha mı iyi burada?

Zeynep Kaya
Zeynep Kaya 31 Temmuz 2026

Kesinlikle dependency injection, singleton artık eski kaldı bence.

Selin A.
Selin A. 01 Ağustos 2026

Kod bloklarını çok beğendim, çok düzenli. Hemen kendi projemde denicem, ellerine sağlık.

Deniz Aydın
Deniz Aydın 01 Ağustos 2026

Teşekkür ederim Selin, kolay gelsin!

Mert Demir
Mert Demir 01 Ağustos 2026

Nesne yönelimli mimari konusunda biraz daha derinleşen örnekler bekliyoruz, tasarım desenlerini de dahil edebilirsin bir sonraki yazıda.

Deniz Aydın
Deniz Aydın 02 Ağustos 2026

Tasarım desenleri serisi üzerinde çalışıyorum, takipte kal!

Elif Şahin
Elif Şahin 03 Ağustos 2026

Ya ben bu sepeti yaparken session'da tutuyorum ama bazen veriler kayboluyo, sende de oluyo mu bu sorun?

Burak Korkmaz
Burak Korkmaz 04 Ağustos 2026

Session süresini kontrol etmelisin, php.ini ayarlarında bi bak istersen.

Caner Yılmaz
Caner Yılmaz 05 Ağustos 2026

Harika bir yazı olmuş Deniz hocam. Özellikle tip güvenliği kısmı projelerimde çok işime yarıyor, eline sağlık.

Deniz Aydın
Deniz Aydın 05 Ağustos 2026

Teşekkürler Caner, tip güvenliği projeyi uzun vadede çok rahatlatıyor.

Yorum Yaz