WDB ile Sorgulama

1.8k görüntülenme Markdown

Tek bir sorgu kurucusu, iki giriş noktası ve tamamlanmadan hiçbir şeyi değiştirmeyen bir zincir.

Genel Bakış

Sorgular, SQL'i bir dizeye yazarak değil çağrıları zincirleyerek kurulur: zincir, ifadenin yazıldığı sırayla okunur ve argüman olarak geçtiğiniz her değer yapıştırılmaz, bağlanır.

WDB statik bir cephedir. Metotlarının her biri, model katmanının tuttuğu tek Database nesnesine yönlenir; yani statik biçim ile bir modelin $this->db'si aynı bağlantı ve aynı kurucu durumudur.

Referans

Giriş Noktaları

WDB:: Statik cephe; yardımcılar, operation'lar, modüller ve kancalar için. Her çağrı aşağıdaki nesneye yönlenir.
$this->db Bir modelin içindeki aynı nesne; Models üzerindeki tembel getter süreç başına bir kez kurar. Bir zincir bir biçimde başlatılıp diğerinde sürdürülebilir.
Database Kurucunun kendisi. Statik sarmalayıcısı olmayan metotlara (whereGroup, getCount, pushState) zincirin döndürdüğü nesne üzerinden erişilir.

Okuma

okuma zinciri ve çekiciler
// Kolonları adlandırın. "*", tablonun sonradan büyüdüğü her şeyi çağıranlarınıza verir.
public static function select($arg = "*");              // boş/yanlış bir $arg "*" olur
public static function from($arg = '');                 // "users_products" | "users_products AS t"
public static function join($type, $table, $where);     // $type: "LEFT" | "INNER" | "RIGHT" - " JOIN " önüne yapıştırılır
public static function where($column, $mark = '', $value = '', $logical = '');
public static function group_by($arg = '');             // ham ifade, bağlanmaz
public static function order_by($arg);                  // ham ifade, bağlanmaz
public static function limit($arg1, $arg2 = null);      // limit(25) -> LIMIT 0,25 · limit(50, 25) -> LIMIT 50,25
public static function build($isthis = false);          // bool: eşleşen satır > 0 · $isthis = true Database nesnesini döner

// Çekiciler build()'in bıraktığı statement'ı ya da elle verdiğinizi okur.
public static function fetch_assoc($statement = false); // satır listesi, her biri kolon => değer; eşleşme yoksa []
public static function getAssoc($statement = false);    // tek satır, kolon => değer; satır yoksa false
public static function fetch_object($statement = false);// aynı liste, stdClass nesneleri olarak
public static function getObject($statement = false);   // tek satır stdClass olarak; satır yoksa false
public static function rowCounter($statement = false);  // int: son statement'ın dokunduğu satır sayısı

where() Neleri Kabul Eder

İkinci argüman ifadeye olduğu gibi yazılır; yani kurucunun sahip olduğu bir listeden gelen anahtar kelime değil, bir SQL operatörüdür. Üç biçim özel olarak ele alınır.

$mark $value Üretilen SQL
'=' '!=' skaler; boş dize de bağlanır col = ?
'>' '<' '>=' '<=' skaler col > ?
'LIKE' 'NOT LIKE' kendi % işaretini taşıyan skaler col LIKE ?
'IN' 'NOT IN' dizi; eleman başına bir yer tutucu col IN (?,?,?)
'IS' 'IS NOT' 'NULL'; bağlanmaz, yapıştırılır col IS NULL
'IS NOT NULL' ''; testin tamamı operatördür col IS NOT NULL
verilmedi ('') boş olmayan skaler col = ?
koşulları bağlama
// $logical yalnız 'AND', '&&', 'OR', '||' kabul eder. BU koşulu BİR SONRAKİNE bağlar;
// operatörsüz bırakılan bir koşula, sonraki koşul geldiğinde otomatik AND eklenir.
public static function where($column, $mark = '', $value = '', $logical = '');

// Parantez: statik sarmalayıcısı yok, zincirin döndürdüğü nesne üzerinden çağrılır.
// $logical grubun tamamını KENDİSİNDEN SONRAKİ koşula bağlar, tıpkı where()'in
// dördüncü argümanı gibi. Vermemek güvenlidir: grup bağlanabilir bir koşul olarak
// kaydedilir, sonraki koşul AND'i kendisi ekler. OR istiyorsanız verin.
public function whereGroup(callable $callback, string $logical = ''): self;

Yazma

yazma zinciri
public static function insert($table, $data);             // int etkilenen satır; SQL hatasında exception fırlatır
public static function lastID();                          // int: eklemenin ürettiği kimlik; bağlantı yoksa 0
public static function update($table = '', $data = []);   // $data boş değilse set()'i sizin yerinize çağırır
public static function set($data = [], $special = false); // $special = true değeri HAM yapıştırır: ['uses' => 'uses+1']
public static function save($isthis = false);             // bool: hata yok - hiçbir satır eşleşmese de TRUE
public static function delete($arg = '', $arg2 = '');     // delete("t") | delete("a", "a INNER JOIN b ON ...")
public static function run($isthis = false);              // bool: silinen satır > 0

// insert() ve update()/set() için $data kolon => değer biçimindedir. null değer SQL NULL,
// tam sayı integer, geri kalan her şey dize olarak bağlanır.
// limit() save() ve run() için de geçerlidir: başlangıçsız satır sayısı, limit(5000).
// order_by() sınırlı bir yazmanın hangi satırları alacağını belirler. İki zincir
// çalışmaz, istisna fırlatır — MySQL kabul etmiyor: update()->join() ve
// order_by()/limit() taşıyan çok tablolu delete("t", "tablo t").

Ham İfadeler

kurucunun dışındaki ifadeler
public static function query($statement, $isthis = false); // PDOStatement ya da false - hata yutulur
public static function exec($arg = '');                    // int etkilenen satır; hatada 0 - hata yutulur
public static function hasTable($table = '');              // bool, SHOW TABLES LIKE ile - ad yapıştırılır, önek eklenmez
public static function getPrefix(): string;                // veritabanı yapılandırmasındaki şema öneki
public static function getErrorMessage();                  // son hatanın metni; yutulanlar da dahil

Örnek

okuma
// Bir sayfa satır.
WDB::select('t.id, t.name, t.status, u.full_name')
    ->from('users_products AS t')
    ->join('LEFT', 'users AS u', 'u.id = t.owner_id')
    ->where('t.status', 'IN', ['active', 'inprocess'])
    ->where('t.type', '=', 'hosting')
    ->order_by('t.id DESC')
    ->limit(0, 25)
    ->build();

$rows = WDB::fetch_assoc();                 // eşleşme yoksa []

// Tek satır. Eşleşme yoksa build() false döner; yazılacak guard budur.
$stmt = WDB::select('id, name, status')->from('users_products')->where('id', '=', $id)->limit(1);
$row  = $stmt->build() ? $stmt->getAssoc() : [];

// Çevresindeki koşullardan yalıtılmış, bağlanmış bir OR grubu.
$search = WDB::select('id')->from('users_products');
$search->where('owner_id', '=', $userId);
$search->whereGroup(function ($q) use ($word) {
    $q->where('name', 'LIKE', '%' . $word . '%', '||');
    $q->where('status', 'LIKE', '%' . $word . '%');
}, '&&');
$search->where('type', '=', 'hosting');
$found = $search->build() ? $search->fetch_assoc() : [];
yazma, sonra yazılanı geri okuma
// insert etkilenen satır sayısını döner; kimlik ardından okunur.
$affected = WDB::insert('users_products', [
    'owner_id'   => $userId,
    'product_id' => $productId,
    'name'       => $name,
    'status'     => 'waiting',
    'notes'      => null,                   // SQL NULL olarak bağlanır
    'cdate'      => DateManager::Now(),
]);
$newId = $affected ? (int) WDB::lastID() : 0;

// Güncelleme: zincir save() çağrılana kadar hiçbir şey yapmaz.
WDB::update('users_products', ['status' => 'active'])->where('id', '=', $newId)->save();

// Bilerek bağlanmayan tek değer: sunucunun hesapladığı bir ifade.
WDB::update('coupons')->set(['uses' => 'uses+1'], true)->where('id', '=', $couponId)->save();

// Yazılanı diğer giriş noktasından geri okuyun - aynı bağlantıdır.
$check = WDB::select('status')->from('users_products')->where('id', '=', $newId);
$saved = $check->build() ? ($check->getAssoc()['status'] ?? '') : '';

// Silme: save() değil, run().
WDB::delete('users_products')->where('id', '=', $newId)->run();

Tuzaklar

Güvenliği sağlayan şey değer argümanıdır

Değeri argüman olarak geçmek onu bağlanmış kılar. Bunun yerine kolon ifadesinin içine kurmak onu ifadenin kendisine taşır ve kullanıcı girdisindeki ilk tırnak bir enjeksiyona dönüşür. Üç yer bilerek bağlanmaz ve asla kullanıcı girdisi almamalıdır: order_by ile group_by, set($data, true) ve hasTable'a verilen tablo adı.

Konumuna göre okunan iki argüman

limit(25) ilk 25 satırdır, limit(50, 25) ise 50. satırdan itibaren 25 satır: bir başlangıç verildiği anda adet ikinci sıraya kayar. where()'in dördüncü argümanı da o koşulu önceki değil sonraki koşula bağlar; yani seçeneğin öncesindeki koşula yazılır, gruptaki son koşula asla.

Bir yazma işlenmeden bitmez, işlenmesi de eşleşme demek değildir

Güncelleme save(), silme run() ister; koşullarda duran bir zincir hiçbir şeyi değiştirmez ve hiçbir şey bildirmez. Dönüş değerleri de bilerek ayrışır: save() "hata yok" cevabını verir, yani koşul hiçbir satırla eşleşmese bile true'dur; run() ve build() ise "satır > 0" cevabını verir. Bir kaydın gerçekten değiştiğini doğrulamak, boolean'a güvenmek değil kaydı geri okumaktır.

Kurucu exception fırlatır, ham ifadeler fırlatmaz

build(), insert(), save() ve run() düşen bir ifadeyi exception'a çevirir; operation katmanı da onu sizin için hata yanıtına dönüştürür. query() ve exec() ise hatayı yutar ve false ya da 0 döner; yani bir şema ifadesi tamamen sessizce başarısız olabilir. Onlara başvurduğunuzda getErrorMessage()'ı okuyun.

Faydalı oldu mu?

Geri bildiriminiz için teşekkürler!

Hâlâ Yardıma mı İhtiyacınız Var?

Yukarıda bulamadığınız her şey için destek ekibimiz her zaman yanınızda.