PHP PDO Kullanarak Güvenli Veritabanı Bağlantısı
Veritabanı güvenliği, web geliştirmenin en kritik aşamalarından biridir. Özellikle kullanıcı girişi alan her sistemde (üyelik, yorum, iletişim formu, admin paneli vb.) hatalı bir veritabanı kullanımı, sitenizi SQL Injection gibi saldırılara açık hale getirebilir.
Eskiden PHP’de sıkça kullanılan mysql_* fonksiyonları (ör. mysql_query) hem güvenlik hem de modern standartlar açısından artık tamamen terk edilmiştir. Günümüzde bunun yerine iki temel yaklaşım vardır: PDO ve MySQLi. Bu yazıda, daha esnek ve taşınabilir bir standart olan PDO (PHP Data Objects) ile güvenli bağlantının nasıl kurulacağını adım adım ele alacağız.
Neden PDO?
1) SQL Injection Koruması
PDO’nun en büyük avantajı, hazırlanmış sorgular (prepared statements) ile çalışmasıdır. prepare ve execute yapısı sayesinde dışarıdan gelen veriler, sorgunun içine “string birleştirerek” eklenmez; parametre olarak bağlanır. Bu da SQL Injection riskini büyük oranda azaltır.
Kötü örnek (yapmayın):
<?php
// KÖTÜ: Kullanıcı verisi doğrudan sorguya ekleniyor
$id = $_GET['id'];
$sql = "SELECT * FROM users WHERE id = $id";
?>
İyi örnek (PDO ile):
<?php
// İYİ: Parametre bağlama var
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $_GET['id']]);
?>
2) Veritabanı Bağımsızlığı
PDO, sadece MySQL ile sınırlı değildir. Aynı kod yapısı ile PostgreSQL, SQLite, MariaDB ve daha pek çok veritabanına bağlanabilirsiniz. Yarın öbür gün MySQL yerine PostgreSQL kullanmak isterseniz, çoğu senaryoda sadece DSN (bağlantı tanımı) tarafını değiştirmeniz yeterli olur.
3) Daha Temiz ve Yönetilebilir Kod
PDO ile hata yönetimini, karakter setini, fetch modlarını ve bağlantı ayarlarını tek bir noktadan yönetebilirsiniz. Bu da projenin büyümesiyle birlikte bakım maliyetini düşürür.
PDO ile Güvenli Veritabanı Bağlantısı Nasıl Kurulur?
PDO bağlantısı kurarken dikkat edilmesi gereken 3 temel nokta vardır:
- Doğru karakter seti (UTF-8 / utf8mb4)
- Hata modu (Exception kullanımı)
- Emülasyonu kapatma (gerçek prepared statement için)
Örnek: MySQL için PDO Bağlantı Yapısı
<?php
$host = "localhost";
$dbname = "veritabani_adi";
$user = "kullanici_adi";
$pass = "sifre";
// DSN: Data Source Name
$dsn = "mysql:host=$host;dbname=$dbname;charset=utf8mb4";
$options = [
// Hataları exception olarak fırlat
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// Varsayılan fetch modu: associative array
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
// Gerçek prepared statements kullan
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
// Bağlantı başarılı
} catch (PDOException $e) {
// Gerçek projede ekrana ham hata basmayın!
// Loglayın ve kullanıcıya genel bir mesaj gösterin.
die("Veritabanı bağlantı hatası.");
}
?>
Bağlantıyı Daha Güvenli Hale Getirmek İçin İpuçları
1) Hata Mesajlarını Kullanıcıya Göstermeyin
PDO hata mesajları tablo isimleri, kolon isimleri gibi kritik detaylar içerebilir. Bu nedenle canlı ortamda kullanıcıya “ham hata” göstermek yerine loglama tercih edilmelidir.
2) Veritabanı Bilgilerini Kod İçine Gömmeyin
Bağlantı bilgilerini mümkünse .env dosyasında tutun veya ayrı bir konfigürasyon dosyası kullanın. Böylece kodu paylaştığınızda şifreler açığa çıkmaz.
3) Minimum Yetki Prensibi (Least Privilege)
Üretim ortamında veritabanı kullanıcısına “root” yetkisi vermek büyük hatadır. Uygulamanın ihtiyaç duyduğu kadar yetki tanımlayın:
- Sadece SELECT gerekiyorsa INSERT/DELETE vermeyin.
- Admin paneli ve frontend farklı kullanıcılarla çalışabilir.
Örnek Kullanım: Güvenli SELECT
<?php
$email = $_POST['email'] ?? '';
$stmt = $pdo->prepare("SELECT id, name, email FROM users WHERE email = :email LIMIT 1");
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();
if ($user) {
echo "Hoş geldin: " . $user['name'];
} else {
echo "Kullanıcı bulunamadı.";
}
?>
Örnek Kullanım: Güvenli INSERT
<?php
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
$stmt->execute([
'name' => $name,
'email' => $email
]);
echo "Kayıt başarıyla eklendi. Yeni ID: " . $pdo->lastInsertId();
?>
Sonuç
PDO, modern PHP projelerinde güvenli veritabanı kullanımının temel taşıdır. Prepared statement desteği sayesinde SQL Injection riskini azaltır, veritabanı bağımsız çalışır ve kodunuzu daha okunabilir hale getirir.