Forum
Soru Sor

titantonnyKullanıcı·24.06.2026 22:33

PHP PDO ile Güvenli MySQL Bağlantısı ve Prepared Statement Kullanımı

1 görüntülenme 0 beğeni 0 cevap
PHP’de veritabanı bağlantısı birkaç satırla kurulabiliyor, fakat güvenli varsayılanlar kullanılmadığında aynı kod ileride SQL injection veya hata yönetimi sorununa dönüşebiliyor. PDO kullanırken bağlantı seçeneklerini ve sorgu parametrelerini baştan doğru kurmak önemli.

Basit bir bağlantı örneği:

php
<?php
$dsn = 'mysql:host=127.0.0.1;dbname=uygulama;charset=utf8mb4';

$pdo = new PDO($dsn, $_ENV['DB_USER'], $_ENV['DB_PASS'], [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false,
]);


Kullanıcı adı ve parolayı doğrudan repoya yazmak yerine ortam değişkeninden veya web kökünün dışındaki güvenli bir yapılandırma dosyasından almak daha doğru. `utf8mb4` seçmek de Türkçe karakterlerle birlikte emoji gibi dört baytlı karakterlerde sorun yaşamayı önlüyor.

Kullanıcı girdisini sorguya birleştirmek yerine prepared statement kullanıyorum:

php
$stmt = $pdo->prepare(
    'SELECT id, username FROM users
     WHERE email = :email AND deleted_at IS NULL
     LIMIT 1'
);
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();


Şu kullanım ise riskli:

php
$sql = "SELECT * FROM users WHERE email = '$email'";


Parametre bağlama yalnızca değerler içindir. Tablo adı, kolon adı veya `ORDER BY` yönü doğrudan placeholder ile bağlanamaz. Böyle dinamik alanlar gerekiyorsa izin verilen değerlerden oluşan beyaz liste kullanmak gerekiyor.

Pratikte dikkat ettiğim diğer noktalar:

- Üretimde ayrıntılı PDO hatalarını ziyaretçiye göstermemek
- Hataları güvenli loga yazmak
- Veritabanı kullanıcısına yalnızca gereken yetkileri vermek
- Parolaları `password_hash` ile saklamak
- Çok adımlı işlemlerde transaction kullanmak
- Sayısal limitleri tamsayıya çevirmek veya doğrulamak
- Aynı named placeholder’ı native prepare modunda tekrar kullanmamaya dikkat etmek

Transaction örneğinde `beginTransaction`, `commit` ve hata halinde `rollBack` birlikte düşünülmeli. İstisna oluştuğunda bağlantının hâlâ transaction içinde olup olmadığını `inTransaction()` ile kontrol etmek faydalı.

PDO tek başına bütün güvenliği çözmez; çıktı verirken XSS’e karşı escape etmek ve yetkilendirmeyi sorgudan bağımsız kontrol etmek de gerekiyor.

Sorgu performansı için prepared statement kullanmak tek başına indeks ihtiyacını ortadan kaldırmaz. Yavaş sorguları ayrı izlemek ve kullanıcıdan gelen arama ifadelerine makul sınır koymak gerekir. Bağlantı hatasında uygulamanın kullanıcıya genel bir mesaj verip teknik ayrıntıyı loglaması daha güvenlidir. Log içine sorgu parametrelerini yazarken parola, token ve kişisel verilerin maskelenmesi de unutulmamalı.

Siz PDO’da native prepare kullanıyor musunuz? Bağlantı ayarlarında eklediğiniz standart seçenekler veya gerçek projede karşılaştığınız ilginç bir hata var mı?

Cevaplar

0 yanıt
Bu konuda henüz cevap yok.