Gereksinimler ve Ön Hazırlık
Projeye başlamadan önce sisteminizde PHP 8.3 veya üzeri bir sürümün yüklü olduğundan emin olun. Modern PHP sürümleri, tip güvenliği (type hinting) ve performans iyileştirmeleri sayesinde stok takip sistemleri için çok daha güvenli bir ortam sunar.
- PHP 8.3+: Modern sözdizimi ve performans özellikleri için gereklidir.
- MySQL/MariaDB: Verilerin kalıcı olarak depolanması için kullanılır.
- PDO (PHP Data Objects): Veritabanı işlemleri için güvenli bir katman sağlar.
- Composer: Gerekli ise bağımlılık yönetimi için kullanılabilir.
Veritabanı Yapısının Tasarlanması
Dinamik bir stok sistemi için ilişkisel bir veritabanı tasarımı şarttır. Ürünlerin ve stok hareketlerinin tutulacağı tabloları oluştururken, veri bütünlüğünü korumak adına Foreign Key (yabancı anahtar) yapılarını kullanacağız.
CREATE TABLE urunler (
id INT AUTO_INCREMENT PRIMARY KEY,
ad VARCHAR(255) NOT NULL,
stok_miktari INT DEFAULT 0,
fiyat DECIMAL(10, 2) NOT NULL,
guncellenme_tarihi TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE TABLE stok_hareketleri (
id INT AUTO_INCREMENT PRIMARY KEY,
urun_id INT,
miktar INT NOT NULL,
islem_tipi ENUM('giris', 'cikis') NOT NULL,
tarih TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (urun_id) REFERENCES urunler(id)
);
Bu SQL kodları, ürünlerin güncel stok durumunu ve geçmişe dönük tüm hareketlerini izleyebileceğimiz bir temel oluşturur. islem_tipi alanı, stokta dinamik bir şekilde artış veya azalış yapmamızı sağlar.
Veritabanı Bağlantısı ve Güvenli Veri Erişimi
Veritabanı işlemlerini nesne yönelimli bir yapıda yönetmek için bir Database sınıfı oluşturmalıyız. Bu sınıf, PDO kullanarak SQL Injection saldırılarına karşı hazırlıklı olmalıdır.
class Database {
private $pdo;
public function __construct($host, $db, $user, $pass) {
$dsn = "mysql:host=$host;dbname=$db;charset=utf8mb4";
$this->pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
}
public function getConnection() {
return $this->pdo;
}
}
Bu sınıf, uygulamanın geri kalanında veritabanı bağlantı nesnesini tek bir noktadan yönetmemizi sağlar. PDO::ERRMODE_EXCEPTION kullanımı, hataların yakalanmasını kolaylaştırır.
Stok Yönetimi İçin Nesne Yönelimli Sınıf Yapısı
Stok işlemlerini yönetmek için bir StokYonetici sınıfı oluşturacağız. Bu sınıf, ürün ekleme, stok güncelleme ve hareket kaydı oluşturma gibi iş mantıklarını (business logic) içerecektir.
class StokYonetici {
private $db;
public function __construct($dbConnection) {
$this->db = $dbConnection;
}
public function stokGuncelle($urunId, $miktar, $tip) {
$this->db->beginTransaction();
try {
// Stok miktarını güncelle
$islem = ($tip === 'giris') ? '+' : '-';
$sql = "UPDATE urunler SET stok_miktari = stok_miktari $islem :miktar WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->execute(['miktar' => $miktar, 'id' => $urunId]);
// Hareketi kaydet
$sqlLog = "INSERT INTO stok_hareketleri (urun_id, miktar, islem_tipi) VALUES (:id, :miktar, :tip)";
$stmtLog = $this->db->prepare($sqlLog);
$stmtLog->execute(['id' => $urunId, 'miktar' => $miktar, 'tip' => $tip]);
$this->db->commit();
} catch (Exception $e) {
$this->db->rollBack();
throw $e;
}
}
}
Bu kodda beginTransaction ve commit kullanarak "Transaction" (işlem birliği) yapısını kullandık. Eğer stok güncelleme veya log kaydı sırasında bir hata oluşursa, veritabanı eski haline döner (rollback), böylece veri tutarsızlığı önlenir.
Stok Hareketlerinin İzlenmesi ve Raporlama
Sistemin dinamik olması için hareketlerin izlenmesi gerekir. Aşağıdaki metod ile belirli bir ürünün stok geçmişini listeleyebiliriz.
public function hareketGecmisi($urunId) {
$stmt = $this->db->prepare("SELECT * FROM stok_hareketleri WHERE urun_id = :id ORDER BY tarih DESC");
$stmt->execute(['id' => $urunId]);
return $stmt->fetchAll();
}
Bu metot, veritabanından ilgili ürünün tüm hareketlerini çekerek dinamik bir raporlama altyapısı sunar. ORDER BY tarih DESC ifadesi, en güncel hareketin en üstte görünmesini sağlar.
Karşılaştırma: Geleneksel vs. Nesne Yönelimli Yaklaşım
| Özellik | Geleneksel (Spagetti) | Nesne Yönelimli (OOP) |
|---|---|---|
| Bakım | Çok Zor | Kolay ve Modüler |
| Güvenlik | Düşük (SQL Injection riski) | Yüksek (PDO/Prepared Statements) |
| Test Edilebilirlik | İmkansıza yakın | Birim testlerine uygun |
Kritik Güvenlik Uyarısı: Üretim ortamında veritabanı şifrelerini asla doğrudan kod içerisinde tutmayın. `.env` dosyaları veya güvenli konfigürasyon yöneticileri kullanarak hassas bilgileri koruyun. Ayrıca, tüm kullanıcı girişlerini mutlaka filtreleyin (sanitization).
Sıkça Sorulan Sorular
Stok takibinde veritabanı kilitlenmelerini nasıl önlerim?
İşlemlerinizi mümkün olduğunca hızlı tamamlayın ve uzun süren sorguları transaction bloklarının dışında tutun. InnoDB motoru satır bazlı kilitleme yaptığı için doğru indeksleme ile performans sorunlarını minimize edebilirsiniz.
Neden PDO kullanmalıyım?
PDO, veritabanından bağımsız bir arayüz sunar ve Prepared Statements (hazırlanmış ifadeler) sayesinde SQL Injection saldırılarına karşı yerleşik koruma sağlar.
Stok miktarının eksiye düşmesini nasıl engellerim?
stokGuncelle metodunuzun içerisine, eğer işlem tipi 'cikis' ise, mevcut stok miktarının istenen miktardan az olup olmadığını kontrol eden bir if bloğu ekleyerek iş mantığı seviyesinde doğrulama yapabilirsiniz.
Sistem ölçeklenebilir mi?
Evet, OOP yapısı sayesinde ileride farklı depo lokasyonları veya farklı ürün tipleri eklemek isterseniz, sadece ilgili sınıfları genişleterek (inheritance) sistemi büyütebilirsiniz.
Log kayıtları çok büyürse ne yapmalıyım?
Log tablolarını belirli aralıklarla arşivlemek veya "Partitioning" (bölümleme) yöntemini kullanarak veritabanı performansını korumak en iyi yöntemdir.
Stok Takip Sisteminde Birim Testleri (Unit Testing) ile Hata Ayıklama
Nesne yönelimli bir yapıda, stok hareketlerinin doğruluğunu garanti altına almak için manuel testler yeterli değildir. PHPUnit gibi araçlar kullanarak, stok güncelleme metodlarınızın beklenen sonuçları verip vermediğini otomatize edebilirsiniz. Özellikle kritik matematiksel işlemlerin (stok düşme, iade alma) test edilmesi, gelecekteki geliştirmelerde sistemin bozulmasını engeller.
Aşağıdaki örnek, StokManager sınıfındaki stokGuncelle metodunun doğruluğunu test etmek için kullanılan temel bir test senaryosunu göstermektedir:
use PHPUnit\Framework\TestCase;
class StokTest extends TestCase {
public function testStokDusumuBasariliMi() {
$stok = new StokManager($pdo);
$baslangicStok = 100;
$miktar = 20;
$sonuc = $stok->stokGuncelle(1, -$miktar);
$yeniStok = $stok->stokGetir(1);
$this->assertTrue($sonuc);
$this->assertEquals(80, $yeniStok);
}
}
Sistem Performansını İyileştirmek İçin İleri İpuçları
Sisteminiz büyüdükçe, her stok sorgusunda tüm veritabanını taramak performans kayıplarına yol açar. Profesyonel bir stok yönetiminde veritabanı sorgularını optimize etmek ve önbellekleme mekanizmaları kullanmak hayati önem taşır.
İndeksleme (Indexing) Stratejileri
Stok tablonuzda urun_id ve depo_id gibi sık sorgulanan sütunlara indeks eklemek, sorgu hızını milisaniyeler seviyesine çeker. Aşağıdaki SQL komutu ile veritabanı performansınızı optimize edebilirsiniz:
-- Stok sorgularını hızlandırmak için indeks oluşturma
CREATE INDEX idx_urun_depo ON stok_hareketleri(urun_id, depo_id);
Redis ile Önbellekleme
Çok yoğun trafik alan bir e-ticaret sisteminde, her sayfada veritabanına gidip stok bilgisini çekmek yerine, güncel stok miktarını Redis gibi bir "In-Memory" veri deposunda tutabilirsiniz. Stok güncellendiğinde Redis üzerindeki değer güncellenir, okuma işlemleri ise doğrudan RAM üzerinden yapılır.
- Okuma Yoğunluğu: Stok bilgisi sık okunuyorsa Redis tercih edin.
- Yazma Yoğunluğu: Stok bilgisi sürekli güncelleniyorsa veritabanı transaction'larına sadık kalın.
- Senkronizasyon: Veritabanı ve önbellek arasındaki tutarlılığı sağlamak için "Write-Through" stratejisini uygulayın.
Profesyonel İpucu: Stok takibinde "Race Condition" (yarış durumu) oluşmaması için SELECT ... FOR UPDATE yapısını kullanarak, işlem tamamlanana kadar ilgili satırı kilitlemeyi unutmayın. Bu, aynı anda iki farklı satışın aynı stoğu tüketmesini engeller.
Sonuç
PHP ile nesne yönelimli bir stok takip sistemi geliştirmek, sadece bir kodlama egzersizi değil, aynı zamanda veriyi yönetme disiplinidir. Bu rehberde öğrendiğiniz PDO kullanımı, transaction yönetimi ve OOP prensipleri, profesyonel projeleriniz için sağlam bir temel oluşturacaktır. Bir sonraki adım olarak, bu sisteme bir kullanıcı yetkilendirme katmanı ekleyerek kimin hangi stoğu güncelleyebileceğini kontrol altına alabilirsiniz.


Yorumlar (0)
Yorum Yaz