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-catchblokları 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.


Yorumlar (0)
Yorum Yaz