Mehmet

WFN Üye
Konular
1,851
Mesajlar
1,852
Çözüm
0
Ticaret Puanı
0
Üyelik
1 Ay 6 Gün
Konum
YurtDışı
Web Sitesi
Var
Alanı
Google Adsense
1/1
Konu sahibi

PHP prepare nedir?​


PHP'de prepare, SQL sorgusunu verilerden ayrı hazırlamayı sağlayan prepared statement yöntemidir. Sorgunun içine değişkenleri metin birleştirmeyle eklemek yerine ? veya :ad gibi yer tutucular kullanılır; gerçek değerler daha sonra execute() ile gönderilir. Bu yaklaşım SQL injection riskini azaltır, yer tutuculara ayrı değer bağlamayı sağlar ve aynı sorgunun farklı değerlerle tekrar kullanılmasını kolaylaştırır.

PHP'de en yaygın kullanım PDO'daki PDO::prepare() metodudur. mysqli kullanıyorsanız karşılığı mysqli_prepare() veya nesne yönelimli arayüzde $mysqli->prepare() metodudur. Aşağıdaki örnek PDO ile çalışır.

PDO prepare nasıl çalışır?​


Hazırlanan sorguda kullanıcıdan gelen veri SQL kodunun parçası olarak değil, parametre değeri olarak ele alınır. Örneğin kullanıcı adı için sorguyu şu şekilde birleştirmek hatalıdır:

Kod:
$sql = "SELECT id FROM users WHERE username = '$username'";

Doğru yaklaşım, sorguyu yer tutucuyla hazırlayıp değeri ayrı vermektir:

Kod:
$statement = $pdo->prepare(
    'SELECT id FROM users WHERE username = :username'
);
$statement->execute(['username' => $username]);

Burada :username bir değerin yerini tutar. Tablo adı, sütun adı veya SQL anahtar kelimesi için kullanılamaz. Örneğin ORDER BY :column sütun adını bağlamaz; sorgu kabul edilse bile beklenen sütuna göre sıralama sağlamaz; dinamik sütun seçimi gerekiyorsa izin verilen sütunları sabit bir listeyle eşleştirmek gerekir.

Çalışan en küçük örnek​


Bu örnek veritabanı sunucusu gerektirmeyen, bellekte çalışan SQLite bağlantısı kullanır. Ön koşul, PHP kurulumunda PDO SQLite sürücüsünün etkin olmasıdır.

  1. Aşağıdaki kodu prepare.php adıyla kaydedin.
  2. Komut satırında php prepare.php komutunu çalıştırın.
  3. Ekrandaki sonucu, sorgunun parametreyle başarıyla çalıştığını doğrulamak için kontrol edin.

Kod:
<?php
declare(strict_types=1);

$pdo = new PDO('sqlite::memory:');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->exec(
    'CREATE TABLE users (
        id INTEGER PRIMARY KEY,
        username TEXT NOT NULL,
        email TEXT NOT NULL
    )'
);

$insert = $pdo->prepare(
    'INSERT INTO users (username, email) VALUES (:username, :email)'
);
$insert->execute([
    'username' => 'ayse',
    'email' => '[email protected]',
]);

$username = 'ayse';
$select = $pdo->prepare(
    'SELECT id, username, email FROM users WHERE username = :username'
);
$select->execute(['username' => $username]);

$user = $select->fetch(PDO::FETCH_ASSOC);

if ($user === false) {
    echo "Kullanıcı bulunamadı\n";
    exit;
}

echo $user['username'] . ' - ' . $user['email'] . "\n";

Beklenen başarı çıktısı şudur:

Kod:

Bu çıktı alınmıyorsa önce PDO SQLite sürücüsünün etkin olup olmadığını ve dosyanın PHP CLI ile çalıştırıldığını kontrol edin. PDOException oluşursa hata mesajı bağlantı, SQL sözdizimi veya tablo oluşturma aşamalarından hangisinin başarısız olduğunu gösterir. MySQL veya PostgreSQL’de de prepare() ve execute() modeli kullanılır; ancak DSN yanında SQL sözdizimi, sürücü seçenekleri ve tür davranışları da kontrol edilmelidir. PDO, farklı veritabanlarının SQL dilini otomatik dönüştürmez.

PDO mu, mysqli mi?​


Her iki yöntem de parametreli sorgu çalıştırabilir. Kullandığınız veritabanı ve projenin mevcut bağlantı katmanı, seçimdeki temel ölçüttür.

ÖzellikPDOMySQLi
Veritabanı desteğiBirden fazla sürücüyle kullanılabilirMySQL ve MariaDB odaklıdır
Yer tutucu türüİsimli veya soru işaretliSoru işaretli
Tip bağlamaGerekirse bindValue() veya bindParam()Genellikle bind_param() ile açık tip belirtilir
Uygun tercihTaşınabilir veya yeni PDO tabanlı uygulamalarYalnızca MySQL uyumlu mevcut projeler

PDO’da hata modu sürüme göre değişebileceğinden örnekte açıkça PDO::ERRMODE_EXCEPTION ayarlanır; başarısız sorguların istisna olarak ele alınmasını sağlar. Üretim kodunda bağlantı bilgilerini kaynak dosyaya sabitlemek yerine uygulamanın yapılandırma mekanizmasından okuyun.

Sık yapılan hatalar​


  1. Değeri sorgu metnine birleştirmek: prepare() çağrılmış olsa bile kullanıcı girdisini ayrıca SQL metnine eklemek korumayı bozar.
  2. Yer tutucuyu tırnak içine almak: WHERE username = ':username' ifadesi parametre olarak değil, sabit metin olarak değerlendirilir. Doğrusu WHERE username = :username biçimidir.
  3. Parametre ile sütun adını değiştirmeye çalışmak: Yer tutucular yalnızca değerler içindir. Sütun adı gerekiyorsa sabit izin listesi kullanın.
  4. Sonuç yokken doğrudan dizi okumak: fetch() sonucu false olabilir; kullanmadan önce bu durumu kontrol edin.
  5. Tekrarlanan sorgularda yanlış beklenti kurmak: prepare() güvenliği ve parametre yönetimini sağlar; her veritabanında otomatik olarak ölçülebilir performans artışı garanti etmez.

Sık sorulan sorular​


prepare ile sorguyu yalnızca bir kez hazırlamak zorunda mıyım?​


Hayır. Bir PDOStatement nesnesini farklı değerlerle tekrar execute() edebilirsiniz. Aynı işlem döngü içinde çok kez yapılacaksa bu kullanım, sorgu metnini her seferinde yeniden kurmaktan daha düzenlidir.

bindValue ile bindParam arasındaki temel fark nedir?​


bindValue() çağrıldığı andaki değeri bağlar. bindParam() ise bir değişkene referans bağlar ve sorgu çalıştırıldığında o değişkenin güncel değerini kullanır. Değişkeni sonradan değiştirmeyecekseniz execute() dizisi veya bindValue() genellikle daha anlaşılırdır.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Konuyu görüntüleyenler

Bu konuyu şu anda görüntüleyen üye bulunmuyor.