İçeriğe geç

XOOPS Sorgu Oluşturucu

XOOPS Sorgu Oluşturucu, SQL sorguları oluşturmak için modern, akıcı bir arayüz sağlar. SQL enjeksiyonunun önlenmesine yardımcı olur, okunabilirliği artırır ve birden fazla database sistemi için database soyutlaması sağlar.

graph TD
A[QueryBuilder] -->|builds| B[SELECT Queries]
A -->|builds| C[INSERT Queries]
A -->|builds| D[UPDATE Queries]
A -->|builds| E[DELETE Queries]
F[Table] -->|chains| G[select]
F -->|chains| H[where]
F -->|chains| I[orderBy]
F -->|chains| J[limit]
G -->|chains| K[join]
G -->|chains| H
H -->|chains| I
I -->|chains| J
L[Execute Methods] -->|returns| M[Results]
L -->|returns| N[Count]
L -->|returns| O[First/Last]

Akıcı arayüze sahip ana sorgu oluşturucu sınıfı.

namespace Xoops\Database;
class QueryBuilder
{
protected string $table = '';
protected string $type = 'SELECT';
protected array $selects = [];
protected array $joins = [];
protected array $wheres = [];
protected array $orders = [];
protected int $limit = 0;
protected int $offset = 0;
protected array $bindings = [];
}

Bir tablo için yeni bir sorgu oluşturucu oluşturur.

public static function table(string $table): QueryBuilder

Parametreler:

ParametreTürAçıklama
$tabledizeTablo adı (önekli veya öneksiz)

Döndürür: QueryBuilder - Sorgu oluşturucu örneği

Örnek:

$query = QueryBuilder::table('users');
$query = QueryBuilder::table('xoops_users'); // With prefix

Seçilecek sütunları belirtir.

public function select(...$columns): self

Parametreler:

ParametreTürAçıklama
...$columnsdiziSütun adları veya ifadeleri

Döndürür: self - Yöntem zincirleme için

Örnek:

// Simple select
QueryBuilder::table('users')
->select('id', 'username', 'email')
->get();
// Select with aliases
QueryBuilder::table('users')
->select('id as user_id', 'username as name')
->get();
// Select all columns
QueryBuilder::table('users')
->select('*')
->get();
// Select with expressions
QueryBuilder::table('orders')
->select('id', 'COUNT(*) as total_items')
->groupBy('id')
->get();

Bir WHERE koşulu ekler.

public function where(string $column, string $operator = '=', mixed $value = null): self

Parametreler:

ParametreTürAçıklama
$columndizeSütun adı
$operatordizeKarşılaştırma operatörü
$valuekarışıkKarşılaştırılacak değer

Döndürür: self - Yöntem zincirleme için

Operatörler:

OperatörAçıklamaÖrnek
=Eşit->where('status', '=', 'active')
!= veya <>Eşit değil->where('status', '!=', 'deleted')
>Şundan büyük:->where('price', '>', 100)
<’dan az
>=Büyük veya eşit->where('age', '>=', 18)
<=Daha az veya eşit->where('age', '<=', 65)
LIKEDesen uyumu->where('name', 'LIKE', '%john%')
INListede->where('status', 'IN', ['active', 'pending'])
NOT INListede yok->where('id', 'NOT IN', [1, 2, 3])
BETWEENMenzil->where('age', 'BETWEEN', [18, 65])
IS NULLBoş->where('deleted_at', 'IS NULL')
IS NOT NULLBoş değil->where('deleted_at', 'IS NOT NULL')

Örnek:

// Single condition
QueryBuilder::table('users')
->select('*')
->where('status', '=', 'active')
->get();
// Multiple conditions (AND)
QueryBuilder::table('users')
->select('*')
->where('status', '=', 'active')
->where('age', '>=', 18)
->get();
// IN operator
QueryBuilder::table('products')
->select('*')
->where('category_id', 'IN', [1, 2, 3])
->get();
// LIKE operator
QueryBuilder::table('users')
->select('*')
->where('email', 'LIKE', '%@example.com')
->get();
// NULL check
QueryBuilder::table('users')
->select('*')
->where('deleted_at', 'IS NULL')
->get();

VEYA koşulu ekler.

public function orWhere(string $column, string $operator = '=', mixed $value = null): self

Örnek:

QueryBuilder::table('users')
->select('*')
->where('status', '=', 'active')
->orWhere('premium', '=', 1)
->get();
// SELECT * FROM users WHERE status = 'active' OR premium = 1

IN/NOT IN için uygun yöntemler.

public function whereIn(string $column, array $values): self
public function whereNotIn(string $column, array $values): self

Örnek:

QueryBuilder::table('posts')
->select('*')
->whereIn('status', ['published', 'scheduled'])
->get();
QueryBuilder::table('comments')
->select('*')
->whereNotIn('spam_score', [8, 9, 10])
->get();

NULL çekleri için uygun yöntemler.

public function whereNull(string $column): self
public function whereNotNull(string $column): self

Örnek:

QueryBuilder::table('users')
->select('*')
->whereNotNull('verified_at')
->get();

Değerin iki değer arasında olup olmadığını kontrol eder.

public function whereBetween(string $column, array $values): self

Örnek:

QueryBuilder::table('products')
->select('*')
->whereBetween('price', [10, 100])
->get();
QueryBuilder::table('orders')
->select('*')
->whereBetween('created_at', ['2024-01-01', '2024-12-31'])
->get();

Bir INNER JOIN ekler.

public function join(
string $table,
string $first,
string $operator = '=',
string $second = null
): self

Örnek:

QueryBuilder::table('posts')
->select('posts.*', 'users.username', 'categories.name')
->join('users', 'posts.user_id', '=', 'users.id')
->join('categories', 'posts.category_id', '=', 'categories.id')
->where('posts.published', '=', 1)
->get();

Alternatif birleştirme türleri.

public function leftJoin(
string $table,
string $first,
string $operator = '=',
string $second = null
): self
public function rightJoin(
string $table,
string $first,
string $operator = '=',
string $second = null
): self

Örnek:

QueryBuilder::table('users')
->select('users.*', 'COUNT(posts.id) as post_count')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->groupBy('users.id')
->get();

Sonuçları sütunlara göre gruplandırır.

public function groupBy(...$columns): self

Örnek:

QueryBuilder::table('orders')
->select('user_id', 'COUNT(*) as order_count', 'SUM(total) as total_spent')
->groupBy('user_id')
->get();
QueryBuilder::table('sales')
->select('department', 'region', 'SUM(amount) as total')
->groupBy('department', 'region')
->get();

Bir HAVING koşulu ekler.

public function having(string $column, string $operator = '=', mixed $value = null): self

Örnek:

QueryBuilder::table('orders')
->select('user_id', 'COUNT(*) as order_count')
->groupBy('user_id')
->having('order_count', '>', 5)
->get();

Sonuçları sipariş eder.

public function orderBy(string $column, string $direction = 'ASC'): self

Parametreler:

ParametreTürAçıklama
$columndizeSütun sipariş etme ölçütü
$directiondizeASC veya DESC

Örnek:

// Single order
QueryBuilder::table('users')
->select('*')
->orderBy('created_at', 'DESC')
->get();
// Multiple orders
QueryBuilder::table('posts')
->select('*')
->orderBy('category_id', 'ASC')
->orderBy('created_at', 'DESC')
->get();
// Random order
QueryBuilder::table('quotes')
->select('*')
->orderBy('RAND()')
->get();

Sonuçları sınırlar ve dengeler.

public function limit(int $limit): self
public function offset(int $offset): self

Örnek:

// Simple limit
QueryBuilder::table('posts')
->select('*')
->limit(10)
->get();
// Pagination
$page = 2;
$perPage = 20;
$offset = ($page - 1) * $perPage;
QueryBuilder::table('posts')
->select('*')
->limit($perPage)
->offset($offset)
->get();

Sorguyu yürütür ve tüm sonuçları döndürür.

public function get(): array

Döndürür: array - Sonuç satırlarının dizisi

Örnek:

$users = QueryBuilder::table('users')
->select('id', 'username', 'email')
->where('status', '=', 'active')
->orderBy('username')
->get();
foreach ($users as $user) {
echo $user['username'] . ' (' . $user['email'] . ')' . "\n";
}

İlk sonucu alır.

public function first(): ?array

Döndürür: ?array - İlk satır veya boş

Örnek:

$user = QueryBuilder::table('users')
->select('*')
->where('id', '=', 123)
->first();
if ($user) {
echo 'Found: ' . $user['username'];
}

Son sonucu alır.

public function last(): ?array

Örnek:

$latestPost = QueryBuilder::table('posts')
->select('*')
->orderBy('created_at', 'DESC')
->last();

Sonuçların sayısını alır.

public function count(): int

Döndürür: int - Satır sayısı

Örnek:

$activeUsers = QueryBuilder::table('users')
->where('status', '=', 'active')
->count();
echo "Active users: $activeUsers";

Sorgunun herhangi bir sonuç döndürüp döndürmediğini kontrol eder.

public function exists(): bool

Döndürür: bool - Sonuçlar mevcutsa doğru

Örnek:

if (QueryBuilder::table('users')->where('email', '=', 'test@example.com')->exists()) {
echo 'User already exists';
}

Toplam değerleri alır.

public function aggregate(string $function, string $column): mixed

Örnek:

$maxPrice = QueryBuilder::table('products')
->aggregate('MAX', 'price');
$avgAge = QueryBuilder::table('users')
->aggregate('AVG', 'age');
$totalSales = QueryBuilder::table('orders')
->aggregate('SUM', 'total');

Bir satır ekler.

public function insert(array $values): bool

Örnek:

QueryBuilder::table('users')->insert([
'username' => 'john',
'email' => 'john@example.com',
'password' => password_hash('secret', PASSWORD_BCRYPT),
'created_at' => date('Y-m-d H:i:s')
]);

Birden çok satır ekler.

public function insertMany(array $rows): bool

Örnek:

QueryBuilder::table('log_entries')->insertMany([
['action' => 'login', 'user_id' => 1, 'timestamp' => time()],
['action' => 'logout', 'user_id' => 2, 'timestamp' => time()],
['action' => 'update', 'user_id' => 3, 'timestamp' => time()]
]);

Satırları günceller.

public function update(array $values): int

Döndürür: int - Etkilenen satır sayısı

Örnek:

// Update single user
QueryBuilder::table('users')
->where('id', '=', 123)
->update([
'email' => 'newemail@example.com',
'updated_at' => date('Y-m-d H:i:s')
]);
// Update multiple rows
QueryBuilder::table('posts')
->where('status', '=', 'draft')
->where('created_at', '<', date('Y-m-d', strtotime('-30 days')))
->update([
'status' => 'archived'
]);

Bir sütunu artırır veya azaltır.

public function increment(string $column, int $amount = 1): int
public function decrement(string $column, int $amount = 1): int

Örnek:

// Increment view count
QueryBuilder::table('posts')
->where('id', '=', 123)
->increment('views');
// Decrement stock
QueryBuilder::table('products')
->where('id', '=', 456)
->decrement('stock', 5);

Satırları siler.

public function delete(): int

Döndürür: int - Silinen satırların sayısı

Örnek:

// Delete single record
QueryBuilder::table('comments')
->where('id', '=', 789)
->delete();
// Delete multiple records
QueryBuilder::table('log_entries')
->where('created_at', '<', date('Y-m-d', strtotime('-30 days')))
->delete();

Tablodaki tüm satırları siler.

public function truncate(): bool

Örnek:

// Clear all sessions
QueryBuilder::table('sessions')->truncate();
QueryBuilder::table('products')
->select('id', 'name', QueryBuilder::raw('price * quantity as total'))
->get();
$recentPostIds = QueryBuilder::table('posts')
->select('id')
->where('created_at', '>', date('Y-m-d', strtotime('-7 days')))
->toSql();
$comments = QueryBuilder::table('comments')
->select('*')
->whereIn('post_id', $recentPostIds)
->get();
public function toSql(): string

Örnek:

$sql = QueryBuilder::table('users')
->select('id', 'username')
->where('status', '=', 'active')
->toSql();
echo $sql;
// SELECT id, username FROM xoops_users WHERE status = ?
<?php
/**
* Get posts with author and category info
*/
$posts = QueryBuilder::table('posts')
->select(
'posts.id',
'posts.title',
'posts.content',
'posts.created_at',
'users.username as author',
'categories.name as category'
)
->join('users', 'posts.user_id', '=', 'users.id')
->join('categories', 'posts.category_id', '=', 'categories.id')
->where('posts.published', '=', 1)
->orderBy('posts.created_at', 'DESC')
->limit(10)
->get();
foreach ($posts as $post) {
echo '<article>';
echo '<h2>' . htmlspecialchars($post['title']) . '</h2>';
echo '<p class="meta">By ' . htmlspecialchars($post['author']) . ' in ' . htmlspecialchars($post['category']) . '</p>';
echo '<p>' . htmlspecialchars($post['content']) . '</p>';
echo '</article>';
}
<?php
/**
* Paginated results
*/
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$perPage = 20;
$offset = ($page - 1) * $perPage;
// Get total count
$total = QueryBuilder::table('articles')
->where('status', '=', 'published')
->count();
// Get page results
$articles = QueryBuilder::table('articles')
->select('*')
->where('status', '=', 'published')
->orderBy('created_at', 'DESC')
->limit($perPage)
->offset($offset)
->get();
// Calculate pagination
$pages = ceil($total / $perPage);
// Display results
foreach ($articles as $article) {
echo '<div class="article">' . htmlspecialchars($article['title']) . '</div>';
}
// Display pagination links
if ($pages > 1) {
echo '<nav class="pagination">';
for ($i = 1; $i <= $pages; $i++) {
if ($i == $page) {
echo '<span class="current">' . $i . '</span>';
} else {
echo '<a href="?page=' . $i . '">' . $i . '</a>';
}
}
echo '</nav>';
}
<?php
/**
* Sales analysis
*/
// Total sales by region
$regionSales = QueryBuilder::table('orders')
->select('region', QueryBuilder::raw('SUM(total) as total_sales'), QueryBuilder::raw('COUNT(*) as order_count'))
->groupBy('region')
->orderBy('total_sales', 'DESC')
->get();
foreach ($regionSales as $region) {
echo $region['region'] . ': $' . number_format($region['total_sales'], 2) . ' (' . $region['order_count'] . ' orders)' . "\n";
}
// Average order value
$avgOrderValue = QueryBuilder::table('orders')
->aggregate('AVG', 'total');
echo 'Average order value: $' . number_format($avgOrderValue, 2);
  1. Parametreli Sorguları Kullan - QueryBuilder parametre bağlamayı otomatik olarak yönetir
  2. Zincir Yöntemleri - Okunabilir kod için akıcı arayüzden yararlanın
  3. Test SQL Çıktısı - Oluşturulan sorguları doğrulamak için toSql()’yi kullanın
  4. Dizinleri Kullan - Sık sorgulanan sütunların dizine eklendiğinden emin olun
  5. Sonuçları Sınırla - Büyük veri kümeleri için her zaman limit() kullanın
  6. Toplamları Kullan - Veritabanının PHP yerine counting/summing yapmasını sağlayın
  7. Çıktıdan Kaçış - Görüntülenen verilerden her zaman htmlspecialchars() ile çıkın
  8. Dizin Performansı - Yavaş sorguları izleyin ve buna göre optimize edin
  • XoopsDatabase - database katmanı ve bağlantıları
  • Kriterler - Eski Kriterlere dayalı sorgulama sistemi
  • ../Core/XoopsObject - Veri nesnesi kalıcılığı
  • ../Module/Module-System - module database işlemleri

Ayrıca bakınız: XOOPS database API