- Konu sahibi
- #1
Kullanıcıdan gelen değerleri SQL metnine birleştirmek yerine
Aşağıdaki varsayımsal örnek, MySQL’de
İsimli
Örneğin
Sorgunun çalışıp sonuç döndürmemesi tek başına bağlantı veya güvenlik hatası anlamına gelmez; girdiyle eşleşen kayıt bulunmamış olabilir. Beklenen kayıt görünmüyorsa, gizli bilgileri kayda dökmeden parametre değerinin doğru kaynaktan geldiğini, türünü ve veritabanında o değere karşılık gelen kayıt bulunup bulunmadığını kontrol edin. SQL hatası oluşuyorsa hata kodunu ve sorgunun parametre sayısıyla gönderilen değerlerin eşleşmesini inceleyin; hassas parametre değerlerini paylaşmadan veritabanı sürücüsü ve hata koduyla sorunu tanımlayın.
PDO::prepare() ile sorgu şablonu oluşturun, değerleri yer tutucularla execute() çağrısında gönderin ve sonucu fetch() ile alın. Böylece kullanıcı girdisi SQL komutunun parçası değil, sorguda kullanılacak veri olur. Tablo veya sütun adları gibi SQL parçaları ise yer tutucuyla bağlanamaz; bunları gerekiyorsa izin verilen sabit seçeneklerden seçin.Bağlantıyı kurup sorguyu hazırlayın
Aşağıdaki varsayımsal örnek, MySQL’de
users tablosunda e-posta adresi arar. DB_HOST, DB_NAME, DB_USER ve DB_PASS değerlerini kendi bağlantı ayarlarınıza göre değiştirin; parola gibi gizli bilgileri herkese açık kaynak koduna koymayın.
PHP:
<?php
$dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8mb4';
$pdo = new PDO($dsn, DB_USER, DB_PASS, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
$email = $_GET['email'] ?? '';
$sql = 'SELECT id, email FROM users WHERE email = :email';
$stmt = $pdo->prepare($sql);
$stmt->execute(['email' => $email]);
$user = $stmt->fetch();
if ($user === false) {
echo 'Kullanıcı bulunamadı.';
} else {
echo 'Kullanıcı bulundu: ' . htmlspecialchars(
$user['email'],
ENT_QUOTES | ENT_SUBSTITUTE,
'UTF-8'
);
}
prepare() sorgu şablonunu, :email ise verinin yerleştirileceği noktayı belirtir. execute() içindeki dizi, email parametresine gelen değeri bağlar. Sorgu eşleşme bulursa fetch() bir satırlık ilişkisel dizi döndürür; bulamazsa false verir. Örnekte ayrıca veritabanından gelen metin HTML olarak gösterilirken htmlspecialchars() uygulanıyor: SQL enjeksiyonuna karşı parametre bağlamak ile tarayıcıda HTML/JavaScript çalıştırılmasını önlemek farklı güvenlik önlemleridir.Yer tutucuları doğru kullanın
İsimli
:email veya konumlu ? yer tutucularından birini seçin; aynı sorguda ikisini karıştırmayın. Her parametreye karşılık bir değer gönderin. İsimli parametre kullanırken aynı adı bir sorguda tekrar kullanmak yerine her kullanım için ayrı ad tanımlamak, sürücü farklılıklarından kaçınmaya yardımcı olur.| Sorgudaki parça | Güvenli yöntem | Örnek |
|---|---|---|
| Değer | Yer tutucu ve execute() ile bağlama | WHERE id =:id |
| Tablo veya sütun adı | Yer tutucu kullanılamaz; sabit izin listesinden seçin | İzin verilen sütun adı eşlemesi |
| Sıralama yönü gibi SQL sözcüğü | Uygulamanın belirlediği seçeneklerle sınırlandırın | ASC veya DESC |
ORDER BY :column yazıp sütun adını execute() ile göndermek, sütunu dinamik seçmez; parametreler SQL değerleri içindir, tanımlayıcı veya SQL sözdizimi değildir. Kullanıcının sıralama seçeneği sunulacaksa gelen değeri ['name' => 'name', 'date' => 'created_at'] gibi kodda tanımlı bir eşlemeyle gerçek sütun adına dönüştürün; tanınmayan seçeneği reddedin. Ardından yalnız bu sabit eşlemeden gelen adı sorgu metnine ekleyin.Hata ve boş sonuçları yorumlayın
PDO::ERRMODE_EXCEPTION veritabanı hatalarını PDOException olarak bildirir. Üretim ortamında istisnayı yakalayıp kullanıcıya genel bir hata gösterin; ayrıntıyı erişimi kısıtlı sunucu kayıtlarına yazın. Parola, tam sorgu girdisi veya kişisel verileri kullanıcıya ya da açık hata çıktısına basmayın. Geçici hata ayıklama kayıtlarını sorun çözüldüğünde kaldırın.Sorgunun çalışıp sonuç döndürmemesi tek başına bağlantı veya güvenlik hatası anlamına gelmez; girdiyle eşleşen kayıt bulunmamış olabilir. Beklenen kayıt görünmüyorsa, gizli bilgileri kayda dökmeden parametre değerinin doğru kaynaktan geldiğini, türünü ve veritabanında o değere karşılık gelen kayıt bulunup bulunmadığını kontrol edin. SQL hatası oluşuyorsa hata kodunu ve sorgunun parametre sayısıyla gönderilen değerlerin eşleşmesini inceleyin; hassas parametre değerlerini paylaşmadan veritabanı sürücüsü ve hata koduyla sorunu tanımlayın.