PDO bağlantısı, hazırlanan ifadeler, CRUD işlemleri ve SQL enjeksiyonunun önlenmesi.
PDO (PHP Data Objects) veritabanı soyutlama katmanıdır. MySQL, SQLite, PostgreSQL gibi farklı veritabanlarıyla aynı kod ile çalışılabilir.
SQL injection en yaygın güvenlik açığıdır. Kullanıcı verisini direkt SQL'e eklemek tehlikelidir. Prepared statement veriyi SQL'den ayırarak güvenlik sağlar.
fetch() bir sonraki satırı döndürür, fetchAll() tüm sonuçları dizi olarak verir. Büyük veri setlerinde fetch() döngüsü bellek tasarrufu sağlar.
<?php
// ── PDO Bağlantısı ──
function baglan(): PDO {
$dsn = "mysql:host=localhost;dbname=kodlab;charset=utf8mb4";
$ayarlar = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // Hataları fırlat
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // İlişkisel dizi
PDO::ATTR_EMULATE_PREPARES => false, // Gerçek prepared
];
return new PDO($dsn, "kullanici", "sifre", $ayarlar);
}
$db = baglan();
// ── TABLO OLUŞTUR ──
$db->exec("CREATE TABLE IF NOT EXISTS kullanicilar (
id INT AUTO_INCREMENT PRIMARY KEY,
ad VARCHAR(100) NOT NULL,
email VARCHAR(150) UNIQUE NOT NULL,
sifre VARCHAR(255) NOT NULL,
aktif TINYINT(1) DEFAULT 1,
olusturuldu DATETIME DEFAULT CURRENT_TIMESTAMP
)");
// ── INSERT ──
function kullaniciEkle(PDO $db, string $ad, string $email, string $sifre): int {
$sifre_hash = password_hash($sifre, PASSWORD_BCRYPT);
$stmt = $db->prepare("
INSERT INTO kullanicilar (ad, email, sifre)
VALUES (:ad, :email, :sifre)
");
$stmt->execute([
':ad' => $ad,
':email' => $email,
':sifre' => $sifre_hash,
]);
return (int) $db->lastInsertId();
}
$id = kullaniciEkle($db, "Furkan", "furkan@mail.com", "Gizli123!");
echo "Eklenen ID: $id\n";
// ── SELECT ──
function kullaniciBul(PDO $db, int $id): ?array {
$stmt = $db->prepare("SELECT id, ad, email, aktif FROM kullanicilar WHERE id = ?");
$stmt->execute([$id]);
$sonuc = $stmt->fetch();
return $sonuc ?: null;
}
function tumKullanicilar(PDO $db, bool $sadece_aktif = true): array {
$sql = "SELECT id, ad, email, olusturuldu FROM kullanicilar";
if ($sadece_aktif) $sql .= " WHERE aktif = 1";
$sql .= " ORDER BY olusturuldu DESC";
return $db->query($sql)->fetchAll();
}
// Arama (LIKE ile)
function kullaniciAra(PDO $db, string $arama): array {
$stmt = $db->prepare("
SELECT id, ad, email FROM kullanicilar
WHERE ad LIKE :arama OR email LIKE :arama
");
$stmt->execute([':arama' => "%$arama%"]);
return $stmt->fetchAll();
}
// ── UPDATE ──
function sifreGuncelle(PDO $db, int $id, string $yeni_sifre): bool {
$stmt = $db->prepare("UPDATE kullanicilar SET sifre = ? WHERE id = ?");
$stmt->execute([password_hash($yeni_sifre, PASSWORD_BCRYPT), $id]);
return $stmt->rowCount() > 0;
}
// ── DELETE ──
function kullanicipasifYap(PDO $db, int $id): bool {
$stmt = $db->prepare("UPDATE kullanicilar SET aktif = 0 WHERE id = ?");
$stmt->execute([$id]);
return $stmt->rowCount() > 0;
}
// ── GİRİŞ DOĞRULAMA ──
function girisYap(PDO $db, string $email, string $sifre): ?array {
$stmt = $db->prepare("SELECT * FROM kullanicilar WHERE email = ? AND aktif = 1");
$stmt->execute([$email]);
$kullanici = $stmt->fetch();
if ($kullanici && password_verify($sifre, $kullanici['sifre'])) {
unset($kullanici['sifre']); // Şifreyi döndürme!
return $kullanici;
}
return null;
}
// ── TRANSACTION ──
function transferYap(PDO $db, int $gonderen, int $alan, float $tutar): void {
try {
$db->beginTransaction();
$db->prepare("UPDATE hesaplar SET bakiye = bakiye - ? WHERE id = ?")->execute([$tutar, $gonderen]);
$db->prepare("UPDATE hesaplar SET bakiye = bakiye + ? WHERE id = ?")->execute([$tutar, $alan]);
$db->commit();
echo "Transfer başarılı!\n";
} catch (Exception $e) {
$db->rollBack(); // Hata varsa geri al
throw new RuntimeException("Transfer başarısız: " . $e->getMessage());
}
}
// ── SAYFALAMA ──
function kullanicilarSayfalanmis(PDO $db, int $sayfa = 1, int $sayfa_basi = 10): array {
$offset = ($sayfa - 1) * $sayfa_basi;
$stmt = $db->prepare("
SELECT id, ad, email FROM kullanicilar
ORDER BY olusturuldu DESC
LIMIT :limit OFFSET :offset
");
$stmt->bindValue(':limit', $sayfa_basi, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$toplam = $db->query("SELECT COUNT(*) FROM kullanicilar")->fetchColumn();
return [
'veri' => $stmt->fetchAll(),
'toplam' => $toplam,
'toplam_sayfa' => ceil($toplam / $sayfa_basi),
'mevcut_sayfa' => $sayfa,
];
}
?>