Zum Inhalt springen

XOOPS Query Builder

Der XOOPS Query Builder bietet eine moderne, fließende Schnittstelle zum Erstellen von SQL-Abfragen. Er hilft, SQL-Injection zu verhindern, verbessert die Lesbarkeit und bietet Datenbankabstraktion für mehrere Datenbanksysteme.

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]

Die Haupt-QueryBuilder-Klasse mit fließender Schnittstelle.

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 = [];
}

Erstellt einen neuen QueryBuilder für eine Tabelle.

public static function table(string $table): QueryBuilder

Parameter:

ParameterTypBeschreibung
$tablestringTabellenname (mit oder ohne Präfix)

Rückgabewert: QueryBuilder - QueryBuilder-Instanz

Beispiel:

$query = QueryBuilder::table('users');
$query = QueryBuilder::table('xoops_users'); // Mit Präfix

Gibt Spalten an, die ausgewählt werden sollen.

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

Parameter:

ParameterTypBeschreibung
...$columnsarraySpaltennamen oder Ausdrücke

Rückgabewert: self - Für Methodenverkettung

Beispiel:

// Einfache Auswahl
QueryBuilder::table('users')
->select('id', 'username', 'email')
->get();
// Auswahl mit Aliasen
QueryBuilder::table('users')
->select('id as user_id', 'username as name')
->get();
// Alle Spalten auswählen
QueryBuilder::table('users')
->select('*')
->get();
// Auswahl mit Ausdrücken
QueryBuilder::table('orders')
->select('id', 'COUNT(*) as total_items')
->groupBy('id')
->get();

Fügt eine WHERE-Bedingung hinzu.

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

Parameter:

ParameterTypBeschreibung
$columnstringSpaltenname
$operatorstringVergleichsoperator
$valuemixedZu vergleichender Wert

Rückgabewert: self - Für Methodenverkettung

Operatoren:

OperatorBeschreibungBeispiel
=Gleich->where('status', '=', 'active')
!= oder <>Nicht gleich->where('status', '!=', 'deleted')
>Größer als->where('price', '>', 100)
<Kleiner als->where('price', '<', 100)
>=Größer oder gleich->where('age', '>=', 18)
<=Kleiner oder gleich->where('age', '<=', 65)
LIKEMustererkennung->where('name', 'LIKE', '%john%')
INIn Liste->where('status', 'IN', ['active', 'pending'])
NOT INNicht in Liste->where('id', 'NOT IN', [1, 2, 3])
BETWEENBereich->where('age', 'BETWEEN', [18, 65])
IS NULLIst null->where('deleted_at', 'IS NULL')
IS NOT NULLIst nicht null->where('deleted_at', 'IS NOT NULL')

Beispiel:

// Einfache Bedingung
QueryBuilder::table('users')
->select('*')
->where('status', '=', 'active')
->get();
// Mehrere Bedingungen (UND)
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-Überprüfung
QueryBuilder::table('users')
->select('*')
->where('deleted_at', 'IS NULL')
->get();

Fügt eine ODER-Bedingung hinzu.

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

Beispiel:

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

Komfortable Methoden für IN/NOT IN.

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

Beispiel:

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

Komfortable Methoden für NULL-Überprüfungen.

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

Beispiel:

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

Überprüft, ob Wert zwischen zwei Werten liegt.

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

Beispiel:

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

Fügt einen INNER JOIN hinzu.

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

Beispiel:

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();

Alternative JOIN-Typen.

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

Beispiel:

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

Gruppiert Ergebnisse nach Spalte(n).

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

Beispiel:

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();

Fügt eine HAVING-Bedingung hinzu.

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

Beispiel:

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

Sortiert Ergebnisse.

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

Parameter:

ParameterTypBeschreibung
$columnstringSpalte zum Sortieren
$directionstringASC oder DESC

Beispiel:

// Einfache Sortierung
QueryBuilder::table('users')
->select('*')
->orderBy('created_at', 'DESC')
->get();
// Mehrfache Sortierungen
QueryBuilder::table('posts')
->select('*')
->orderBy('category_id', 'ASC')
->orderBy('created_at', 'DESC')
->get();
// Zufällige Sortierung
QueryBuilder::table('quotes')
->select('*')
->orderBy('RAND()')
->get();

Begrenzt und versetzt Ergebnisse.

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

Beispiel:

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

Führt Abfrage aus und gibt alle Ergebnisse zurück.

public function get(): array

Rückgabewert: array - Array von Ergebniszeilen

Beispiel:

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

Holt das erste Ergebnis.

public function first(): ?array

Rückgabewert: ?array - Erste Zeile oder null

Beispiel:

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

Holt das letzte Ergebnis.

public function last(): ?array

Beispiel:

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

Holt die Anzahl der Ergebnisse.

public function count(): int

Rückgabewert: int - Anzahl der Zeilen

Beispiel:

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

Überprüft, ob Abfrage Ergebnisse zurückgibt.

public function exists(): bool

Rückgabewert: bool - True wenn Ergebnisse existieren

Beispiel:

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

Holt Aggregatwerte.

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

Beispiel:

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

Fügt eine Zeile ein.

public function insert(array $values): bool

Beispiel:

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')
]);

Fügt mehrere Zeilen ein.

public function insertMany(array $rows): bool

Beispiel:

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()]
]);

Aktualisiert Zeilen.

public function update(array $values): int

Rückgabewert: int - Anzahl der betroffenen Zeilen

Beispiel:

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

Erhöht oder vermindert eine Spalte.

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

Beispiel:

// Aufrufscount erhöhen
QueryBuilder::table('posts')
->where('id', '=', 123)
->increment('views');
// Lagerbestand verringern
QueryBuilder::table('products')
->where('id', '=', 456)
->decrement('stock', 5);

Löscht Zeilen.

public function delete(): int

Rückgabewert: int - Anzahl der gelöschten Zeilen

Beispiel:

// Einzelnen Datensatz löschen
QueryBuilder::table('comments')
->where('id', '=', 789)
->delete();
// Mehrere Datensätze löschen
QueryBuilder::table('log_entries')
->where('created_at', '<', date('Y-m-d', strtotime('-30 days')))
->delete();

Löscht alle Zeilen aus der Tabelle.

public function truncate(): bool

Beispiel:

// Alle Sessions leeren
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

Beispiel:

$sql = QueryBuilder::table('users')
->select('id', 'username')
->where('status', '=', 'active')
->toSql();
echo $sql;
// SELECT id, username FROM xoops_users WHERE status = ?
  1. Verwenden Sie parametrisierte Abfragen - QueryBuilder handhabt Parameter Binding automatisch
  2. Verketten Sie Methoden - Nutzen Sie die fließende Schnittstelle für lesbaren Code
  3. Testen Sie SQL-Ausgabe - Verwenden Sie toSql(), um generierte Abfragen zu überprüfen
  4. Verwenden Sie Indizes - Stellen Sie sicher, dass häufig abgefragte Spalten indexiert sind
  5. Begrenzen Sie Ergebnisse - Verwenden Sie immer limit() für große Datenmengen
  6. Nutzen Sie Aggregate - Lassen Sie die Datenbank zählen/summieren statt PHP
  7. Escape-Ausgabe - Escapen Sie immer angezeigte Daten mit htmlspecialchars()
  8. Indexleistung überwachen - Überwachen Sie langsame Abfragen und optimieren Sie entsprechend
  • XoopsDatabase - Datenbankschicht und Verbindungen
  • Criteria - Älteres Criteria-basiertes Abfragesystem
  • ../Core/XoopsObject - Datenpersistenz von Objekten
  • ../Module/Module-System - Modul-Datenbankoperationen

Siehe auch: XOOPS Database API