Php İle Nesne Yönelimli Yapıda Dinamik Bir Sipariş Takip Sistemi Nasıl Yapılır?

Php İle Nesne Yönelimli Yapıda Dinamik Bir Sipariş Takip Sistemi Nasıl Yapılır?
Php İle Nesne Yönelimli Yapıda Dinamik Bir Sipariş Takip Sistemi Nasıl Yapılır?

PHP ile Nesne Yönelimli Yapıda Dinamik Bir Sipariş Takip Sistemi Nasıl Yapılır?

Modern web uygulamalarında e-ticaret süreçlerini yönetmek, ölçeklenebilir ve sürdürülebilir bir mimari gerektirir. PHP ile nesne yönelimli yapıda (OOP) dinamik bir sipariş takip sistemi geliştirmek, kodunuzun modüler olmasını sağlar ve gelecekteki değişikliklere karşı dirençli hale getirir. Bu rehberde, 2026 standartlarına uygun olarak, veritabanı etkileşimlerinden nesne modellemeye kadar adım adım profesyonel bir sistemin nasıl inşa edileceğini öğreneceksiniz.

Bu eğitim, PHP 8.x ve üzeri sürümlerin sunduğu modern özellikleri kullanarak temiz kod yazmayı hedefleyen yazılım geliştiriciler içindir. Sipariş oluşturma, durum güncelleme ve veri sorgulama süreçlerini kapsayan bu rehber, kurumsal projelerinizde temel oluşturacak bir yapı sunar.

Gereksinimler ve Ön Hazırlık

Sistemi başarıyla kurabilmek için geliştirme ortamınızda aşağıdaki araçların ve sürümlerin yüklü olduğundan emin olmalısınız:

  • PHP 8.2 veya üzeri: Tip güvenliği (type hinting) ve modern özellikler için gereklidir.
  • MySQL veya MariaDB: Verilerin kalıcı depolanması için.
  • PDO (PHP Data Objects): Veritabanı işlemlerinde SQL injection saldırılarına karşı güvenli bir katman sağlar.
  • Composer: Gerekli görüldüğünde kütüphane yönetimi için.

Projenizi başlatmadan önce veritabanınızda orders adında bir tablo oluşturduğunuzdan emin olun. Bu tablo; id, customer_name, product_id, status ve created_at sütunlarını içermelidir.

Nesne Yönelimli Sipariş Sınıfının Tasarlanması

Nesne yönelimli programlamada temel amaç, veriyi ve bu veriyi işleyen yöntemleri bir arada tutan sınıflar oluşturmaktır. İlk adım olarak Order sınıfımızı tanımlayalım. Bu sınıf, bir siparişin tüm özelliklerini tutacak ve durumunu değiştirecektir.


class Order {
    private int $id;
    private string $customerName;
    private string $status;

    public function __construct(int $id, string $customerName, string $status = 'beklemede') {
        $this->id = $id;
        $this->customerName = $customerName;
        $this->status = $status;
    }

    public function getStatus(): string {
        return $this->status;
    }

    public function setStatus(string $newStatus): void {
        $this->status = $newStatus;
    }
}

Bu sınıf, sipariş nesnesini temsil eder. Kapsülleme (encapsulation) prensibi gereği özellikleri private olarak tanımladık ve erişimi public metotlarla sağladık. Bu, verinin dışarıdan kontrolsüz değiştirilmesini engeller.

Veritabanı Bağlantısı ve PDO Kullanımı

Veritabanı bağlantısını yönetmek için bir Database sınıfı oluşturmak, bağlantı bilgilerini tek bir noktada toplamanıza olanak tanır. PDO kullanımı, SQL injection gibi güvenlik açıklarını önlemek için zorunludur.


class Database {
    private static ?PDO $instance = null;

    public static function getConnection(): PDO {
        if (self::$instance === null) {
            $dsn = 'mysql:host=localhost;dbname=siparis_db;charset=utf8mb4';
            self::$instance = new PDO($dsn, 'kullanici_adi', 'sifre', [
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
            ]);
        }
        return self::$instance;
    }
}

Bu yapı, Singleton tasarım desenini kullanarak uygulama boyunca tek bir veritabanı bağlantısı oluşturur ve kaynak tüketimini optimize eder.

Sipariş Yönetimi İçin Repository Deseni

Repository deseni, veritabanı sorgularını iş mantığından ayırır. Bu sayede siparişleri veritabanından çekmek veya güncellemek için OrderRepository sınıfını kullanırız.


class OrderRepository {
    private PDO $db;

    public function __construct(PDO $db) {
        $this->db = $db;
    }

    public function findById(int $id): ?array {
        $stmt = $this->db->prepare("SELECT * FROM orders WHERE id = :id");
        $stmt->execute(['id' => $id]);
        return $stmt->fetch() ?: null;
    }

    public function updateStatus(int $id, string $status): bool {
        $stmt = $this->db->prepare("UPDATE orders SET status = :status WHERE id = :id");
        return $stmt->execute(['status' => $status, 'id' => $id]);
    }
}

Bu sınıf, SQL sorgularını izole eder. Eğer ileride veritabanı yapısını değiştirirseniz, sadece bu sınıfı güncellemeniz yeterli olacaktır.

Dinamik Sipariş Takip Süreci Nasıl Çalışır?

Dinamik yapı, siparişin durumuna göre farklı işlemler yapabilme yeteneğidir. Örneğin, sipariş "tamamlandı" statüsüne geçtiğinde otomatik bir e-posta gönderimi tetiklenebilir. Bu süreci yönetmek için bir OrderService sınıfı oluşturabiliriz.


class OrderService {
    private OrderRepository $repository;

    public function __construct(OrderRepository $repository) {
        $this->repository = $repository;
    }

    public function processStatusChange(int $id, string $newStatus): void {
        // Burada ek iş mantığı (loglama, bildirim vb.) eklenebilir
        $this->repository->updateStatus($id, $newStatus);
    }
}

Bu katman, uygulamanızın "beyni" gibidir. İş mantığını burada toplayarak, kodun okunabilirliğini ve test edilebilirliğini artırırsınız.

Sistem Karşılaştırması

Yöntem Avantaj Dezavantaj
Procedural (Fonksiyonel) Hızlı başlangıç Bakımı zor, kod tekrarı
Nesne Yönelimli (OOP) Modüler, ölçeklenebilir Öğrenme eğrisi daha yüksek
Kritik Güvenlik Uyarısı: Üretim ortamında veritabanı şifrelerini asla kod dosyalarının içine yazmayın. Bunun yerine .env dosyaları ve getenv() fonksiyonunu kullanarak ortam değişkenlerini yönetin. Ayrıca, kullanıcıdan gelen her veriyi mutlaka htmlspecialchars() veya benzeri fonksiyonlarla XSS saldırılarına karşı filtreleyin.

Sıkça Sorulan Sorular

Neden PDO kullanmalıyım?

PDO, veritabanı bağımsız çalışmanıza olanak tanır ve hazırlanan ifadeler (prepared statements) sayesinde SQL injection saldırılarına karşı en güvenli yöntemdir.

Nesne Yönelimli Yapı performansı düşürür mü?

Modern PHP sürümlerinde nesne yönelimli yapının performans üzerindeki etkisi ihmal edilebilir düzeydedir. Sağladığı bakım kolaylığı ve temiz kod avantajları, performans kaybından çok daha değerlidir.

Repository deseni zorunlu mu?

Zorunlu değildir ancak orta ve büyük ölçekli projelerde veritabanı işlemlerini iş mantığından ayırmak için en iyi pratiklerden biridir.

Hata ayıklama (Debug) için ne yapmalıyım?

Geliştirme ortamında display_errors ayarını açık tutun ve try-catch blokları kullanarak veritabanı hatalarını yakalayıp loglayın.

Sistemimi nasıl daha güvenli hale getiririm?

SSL/TLS sertifikası kullanın, parolaları hashleyerek saklayın (password_hash) ve oturum yönetimi için güvenli çerez parametrelerini yapılandırın.

Sistem Performansını Optimize Etme ve İleri Seviye İpuçları

Sipariş takip sisteminiz büyüdükçe ve veritabanındaki kayıt sayısı arttıkça, sorgu süreleri ve bellek kullanımı kritik bir hal alır. Nesne yönelimli yapınızı korurken performansı artırmak için şu stratejileri uygulayabilirsiniz:

Veritabanı İndeksleme Stratejisi

Siparişlerinizi order_id veya customer_id üzerinden sorgularken, veritabanı tablonuzda bu sütunlar için indeks oluşturulmadığında sistem tam tablo taraması (full table scan) yapar. Bu durumu engellemek için SQL tarafında şu optimizasyonu yapın:

-- Sipariş sorgularını hızlandırmak için indeks ekleme
CREATE INDEX idx_customer_id ON orders(customer_id);
CREATE INDEX idx_status ON orders(status);

Nesne Önbellekleme (Caching)

Her sipariş detayını her sayfa yüklenişinde veritabanından çekmek yerine, sık erişilen veriler için Redis veya Memcached gibi bir önbellekleme katmanı kullanabilirsiniz. Repository sınıfınızda veritabanına gitmeden önce önbelleği kontrol eden bir yapı kurun:

public function getOrderById($id) {
    $cacheKey = "order_" . $id;
    $cachedOrder = $this->cache->get($cacheKey);

    if ($cachedOrder) {
        return unserialize($cachedOrder);
    }

    $order = $this->db->query("SELECT * FROM orders WHERE id = ?", [$id]);
    $this->cache->set($cacheKey, serialize($order), 3600); // 1 saat önbellekle
    return $order;
}

Birim Testleri (Unit Testing) ile Sistem Kararlılığı

Sipariş takip sisteminizin gelecekteki güncellemelerde bozulmadığından emin olmak için PHPUnit kütüphanesini kullanmalısınız. Özellikle Order sınıfınızın hesaplama mantığını test etmek, hataları üretim ortamına çıkmadan yakalamanızı sağlar.

Örnek Test Senaryosu

Sipariş toplam tutarının doğru hesaplanıp hesaplanmadığını kontrol eden basit bir test sınıfı:

use PHPUnit\Framework\TestCase;

class OrderTest extends TestCase {
    public function testCalculateTotal() {
        $order = new Order();
        $order->addItem(['price' => 100, 'qty' => 2]);
        $order->addItem(['price' => 50, 'qty' => 1]);
        
        $this->assertEquals(250, $order->getTotal());
    }
}

Test Sürecinde Dikkat Edilmesi Gerekenler

  • Mocking: Veritabanı bağlantılarını test ederken gerçek veritabanı yerine Mock nesneleri kullanarak testlerin hızlı çalışmasını sağlayın.
  • Edge Cases: Stokta olmayan ürünler, negatif adet girişi veya boş sepet gibi uç durumları mutlaka test senaryolarınıza ekleyin.
  • CI/CD Entegrasyonu: GitHub Actions veya GitLab CI kullanarak, her kod gönderiminde (push) testlerinizin otomatik çalışmasını sağlayın.

Bu ileri seviye yaklaşımlar, sisteminizi sadece "çalışan" bir yapıdan, "ölçeklenebilir ve profesyonel" bir yazılım mimarisine dönüştürecektir. Özellikle birim testleri, uzun vadeli projelerde kodun sürdürülebilirliği için vazgeçilmez bir yatırımdır.

Sonuç

PHP ile nesne yönelimli bir sipariş takip sistemi geliştirmek, sadece kod yazmak değil, aynı zamanda yazılım mimarisini yönetmeyi öğrenmektir. Bu rehberde öğrendiğiniz Order, Database ve Repository sınıfları, sisteminizin temelini oluşturur. Bir sonraki adım olarak, bu sisteme bir "Observer" (Gözlemci) tasarım deseni ekleyerek sipariş durumu değiştiğinde otomatik e-posta gönderen bir modül geliştirmeyi deneyebilirsiniz. İyi çalışmalar dilerim.

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 (0)

Yorum Yaz