PHP ile Nesne Yönelimli Bir Sepet Modülü Nasıl Yapılır?
Modern web uygulamalarında e-ticaret altyapısının kalbi, kullanıcıların ürünleri seçip yönettiği sepet modülüdür. PHP ile nesne yönelimli bir sepet modülü nasıl yapılır sorusuna yanıt ararken, sadece kod yazmayı değil, aynı zamanda veriyi nasıl güvenli ve sürdürülebilir bir şekilde yöneteceğinizi öğreneceksiniz. Bu rehber, PHP 8.x ve üzeri sürümlerin sunduğu modern özellikleri kullanarak, ölçeklenebilir bir yapı kurmanıza yardımcı olacaktır.
Bu makale, nesne yönelimli programlama (OOP) prensiplerini kullanarak, kod tekrarından kaçınan, modüler ve test edilebilir bir sepet yapısı geliştirmek isteyen yazılımcılar için hazırlanmıştır. Adım adım ilerleyerek, veritabanı bağımsız bir yapı kurgulayacak ve sepet işlemlerini sınıf tabanlı bir mimariye oturtacağız.
Gereksinimler ve Ön Hazırlık
Bu projeyi hayata geçirmek için bilgisayarınızda PHP 8.2 veya daha yeni bir sürümün yüklü olması gerekmektedir. Nesne yönelimli yapıyı desteklemek adına modern bir geliştirme ortamı (VS Code, PhpStorm vb.) kullanmanız önerilir. Ayrıca, sepet verilerini kalıcı hale getirmek için bir veritabanı (MySQL veya MariaDB) ve PHP'nin oturum (session) yönetimini nasıl ele aldığını bilmeniz yeterlidir.
- PHP 8.2+ (Constructor property promotion ve tip güvenliği için).
- Composer (İsteğe bağlı, ancak PSR standartlarına uyum için önerilir).
- Bir yerel sunucu ortamı (XAMPP, Laragon veya Docker).
Ürün Sınıfını Oluşturma
Sepet modülünün en temel yapı taşı Product (Ürün) sınıfıdır. Bu sınıf, ürünün özelliklerini (ID, isim, fiyat) tutacak ve verilerin tutarlılığını sağlayacaktır. PHP 8'in getirdiği Constructor Property Promotion özelliğini kullanarak kodumuzu sadeleştiriyoruz.
class Product {
public function __construct(
public int $id,
public string $name,
public float $price
) {}
}
Yukarıdaki kod bloğu, ürün nesnesini tanımlar. public erişim belirleyicisi ile özellikleri doğrudan erişilebilir kıldık. Bu yapı, veritabanından gelen verileri nesneye dönüştürürken büyük kolaylık sağlar.
Sepet (Cart) Sınıfının Tasarımı
Sepet sınıfı, ürünlerin eklenmesi, çıkarılması ve toplam tutarın hesaplanması gibi işlemleri yönetir. Burada array kullanarak ürünleri bellekte tutacağız. Sepet işlemlerinde Encapsulation (Kapsülleme) prensibine uyarak, sepet verisini dışarıdan doğrudan müdahaleye kapatıyoruz.
class Cart {
private array $items = [];
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] = [
'product' => $product,
'quantity' => $quantity
];
}
}
public function getItems(): array {
return $this->items;
}
}
Bu sınıf, sepete ürün ekleme mantığını yönetir. Eğer ürün zaten sepette varsa miktarı artırır, yoksa yeni bir giriş oluşturur. Bu, sepetin tutarlı kalmasını sağlayan temel mantıktır.
Oturum Yönetimi ile Sepeti Kalıcı Hale Getirme
PHP'de sepetin sayfalar arasında taşınabilmesi için $_SESSION kullanılması gerekir. Nesneleri oturumda saklarken dikkatli olmalısınız; çünkü PHP nesneleri serileştirirken (serialize) sınıfların tanımlı olmasını bekler. Aşağıdaki örnekte, sepetin oturumda nasıl saklanacağını görebilirsiniz.
session_start();
function getCart(): Cart {
if (!isset($_SESSION['cart'])) {
$_SESSION['cart'] = new Cart();
}
return $_SESSION['cart'];
}
$cart = getCart();
$product = new Product(1, 'Laptop', 25000.00);
$cart->add($product, 1);
$_SESSION['cart'] = $cart;
Bu yaklaşım, kullanıcının sepetinin tarayıcıyı kapatsa bile (oturum süresi boyunca) korunmasını sağlar. Ancak, büyük ölçekli uygulamalarda veritabanı tabanlı sepet yönetimi daha güvenli bir tercihtir.
Sepet İşlemlerinde Güvenlik ve Hesaplama
Sepet hesaplamalarında kayan noktalı sayı hatalarından kaçınmak için fiyatları kuruş bazlı (integer) tutmak veya bcmath kütüphanesini kullanmak önemlidir. Ayrıca, kullanıcıdan gelen miktarı mutlaka doğrulamalısınız.
public function getTotal(): float {
$total = 0;
foreach ($this->items as $item) {
$total += $item['product']->price * $item['quantity'];
}
return $total;
}
Bu metot, sepetin toplam tutarını dinamik olarak hesaplar. Güvenlik tarafında, sepete eklenen ürünlerin fiyatlarını veritabanından tekrar kontrol etmeyi unutmayın; kullanıcı tarayıcı konsolundan fiyatı değiştiremez ancak sunucu tarafında her zaman veritabanı verisini esas almalısınız.
Kritik Güvenlik Uyarısı: Sepet fiyatlarını asla sadece istemci tarafında (JavaScript) hesaplayıp ödeme adımına göndermeyin. Ödeme aşamasında, sunucu tarafında ürün ID'lerini kullanarak veritabanından güncel fiyatları tekrar çekin. Aksi takdirde, kullanıcılar fiyat manipülasyonu yapabilir.
Karşılaştırma: Sepet Yönetim Yöntemleri
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Session Tabanlı | Hızlı, kurulumu kolay | Sunucu yükü, oturum süresi kısıtı |
| Veritabanı Tabanlı | Kalıcı, çoklu cihaz desteği | Daha fazla veritabanı sorgusu |
| Cookie Tabanlı | Sunucu yükü yok | Güvenlik riski, boyut kısıtı |
Sıkça Sorulan Sorular
Sepet verilerini veritabanında tutmalı mıyım?
Evet, eğer kullanıcının sepetini farklı cihazlarda (mobil, masaüstü) görmesini istiyorsanız, veritabanı tabanlı bir yapı (User ID ile ilişkilendirilmiş) en sağlıklı yöntemdir.
Nesneleri oturumda saklamak performans sorunu yaratır mı?
Küçük ve orta ölçekli sepetler için sorun yaratmaz. Ancak çok sayıda ürün içeren sepetlerde nesne serileştirme maliyeti artabilir; bu durumda sadece ID ve miktar bilgilerini saklamak daha verimlidir.
Fiyat hesaplamalarında neden float kullanmamalıyım?
PHP'de float işlemleri bazen hassasiyet kaybına uğrar (örneğin 0.1 + 0.2 != 0.3). Parasal işlemlerde mutlaka bcmath kütüphanesini veya fiyatları kuruş cinsinden tam sayı olarak kullanmayı tercih edin.
Sepet modülünü nasıl test edebilirim?
PHPUnit kullanarak Cart sınıfınız için birim testler yazabilirsiniz. Sepete ürün ekleme, çıkarma ve toplam hesaplama metotlarını farklı senaryolarla test etmek, uygulamanızın hatasız çalışmasını sağlar.
XSS saldırılarına karşı ne yapmalıyım?
Sepet içeriğini ekrana basarken htmlspecialchars() fonksiyonunu kullanarak tüm çıktıları filtrelemelisiniz. Kullanıcıdan gelen hiçbir veriye doğrudan güvenmeyin.
Sepet Modülünde Performans Optimizasyonu ve Önbellekleme
Sepet modülünüz büyüdükçe ve kullanıcı trafiğiniz arttıkça, her sayfa yüklemesinde oturum (session) verilerini işlemek sunucu üzerinde ek yük oluşturabilir. Özellikle binlerce ürünün olduğu veya karmaşık indirim kurallarının uygulandığı sistemlerde, sepet verilerini optimize etmek kritik bir öneme sahiptir.
Performansı artırmak için sepet verilerini serialize ederek saklamak yerine, sadece gerekli olan ürün ID'lerini ve miktarlarını oturumda tutmalı, ürün detaylarını ise ihtiyaç duyulduğunda veritabanından veya bir önbellek katmanından (Redis gibi) çekmelisiniz.
Redis ile Sepet Verisi Tutma
Oturum dosyalarının diskte tutulması yerine Redis kullanmak, sepet işlemlerini çok daha hızlı hale getirir. İşte bir Redis istemcisi kullanarak sepet verisini yönetmek için temel bir yaklaşım:
// Redis bağlantısı (PhpRedis kütüphanesi ile)
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// Sepeti Redis'e kaydetme
$cartData = json_encode($cartItems);
$redis->set("user_cart_{$userId}", $cartData, 3600); // 1 saatlik ömür
// Sepeti Redis'ten çekme
$data = $redis->get("user_cart_{$userId}");
$cart = json_decode($data, true);
Hata Ayıklama ve Loglama Stratejileri
Sepet modülünde yaşanan hatalar doğrudan satış kaybına yol açar. Bu nedenle, sepetin hesaplama mantığında veya oturum yönetiminde bir sorun oluştuğunda bunu izleyebilmeniz gerekir. PHP'nin error_log fonksiyonunu veya Monolog gibi profesyonel kütüphaneleri kullanarak kritik işlemleri loglamalısınız.
Kritik İşlemleri Loglama Örneği
Özellikle fiyat hesaplamaları ve stok kontrolü gibi hassas noktalarda loglama yapmak, olası bir tutarsızlık durumunda hatanın kaynağını bulmanızı sağlar.
public function calculateTotal() {
try {
$total = 0;
foreach ($this->items as $item) {
if ($item->price < 0) {
throw new Exception("Negatif fiyat hatası: Ürün ID " . $item->id);
}
$total += $item->price * $item->quantity;
}
return $total;
} catch (Exception $e) {
error_log("Sepet Hesaplama Hatası: " . $e->getMessage());
return 0;
}
}
Loglama yaparken dikkat etmeniz gerekenler:
- Hassas Veriler: Kullanıcıların kredi kartı bilgileri veya kişisel verilerini asla log dosyalarına yazdırmayın.
- Log Seviyeleri: Hataları
ERROR, bilgilendirme mesajlarınıINFOseviyesinde tutarak log dosyalarınızın yönetilebilir kalmasını sağlayın. - Dosya İzinleri: Log dosyalarının web sunucusu tarafından yazılabilir ancak dışarıdan erişilemez (public dizin dışında) olduğundan emin olun.
Sonuç
PHP ile nesne yönelimli bir sepet modülü oluşturmak, sadece bir kodlama pratiği değil, aynı zamanda güvenli e-ticaret uygulamaları geliştirmenin temelidir. Bu rehberde öğrendiğiniz OOP prensipleri, oturum yönetimi ve güvenlik önlemleri, projelerinizi bir üst seviyeye taşımanızı sağlayacaktır. Bir sonraki adım olarak, bu modülü bir veritabanı ile entegre edebilir ve kullanıcıların sepetlerini veritabanında kalıcı hale getirecek bir DatabaseCartRepository sınıfı yazmayı deneyebilirsiniz.
Sorumluluk Reddi: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce mutlaka kapsamlı güvenlik testlerinden geçirmeli ve güncel güvenlik kütüphanelerini kullanmalısınız.


Yorumlar (0)
Yorum Yaz