XOOPS Pembina Pertanyaan
Pembina Pertanyaan XOOPS menyediakan antara muka moden yang lancar untuk membina pertanyaan SQL. Ia membantu menghalang suntikan SQL, meningkatkan kebolehbacaan dan menyediakan abstraksi pangkalan data untuk berbilang sistem pangkalan data.## Seni Bina Pembina Pertanyaan
mermaidgraph 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]Kelas QueryBuilderKelas pembina pertanyaan utama dengan antara muka yang lancar.### Gambaran Keseluruhan Kelas
Section titled “Kelas QueryBuilderKelas pembina pertanyaan utama dengan antara muka yang lancar.### Gambaran Keseluruhan Kelas”phpnamespace 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 = [];}Kaedah Statik#### mejaMencipta pembina pertanyaan baharu untuk jadual.
Section titled “Kaedah Statik#### mejaMencipta pembina pertanyaan baharu untuk jadual.”phppublic static function table(string $table): QueryBuilderParameter:| Parameter | Taip | Penerangan |
|-----------|------|-------------|
| $table | rentetan | Nama jadual (dengan atau tanpa awalan) |Pemulangan: QueryBuilder - Contoh pembina pertanyaanContoh:
php$query = QueryBuilder::table('users');$query = QueryBuilder::table('xoops_users'); // With prefixSELECT Pertanyaan### pilihMenentukan lajur untuk dipilih.
Section titled “SELECT Pertanyaan### pilihMenentukan lajur untuk dipilih.”phppublic function select(...$columns): selfParameter:| Parameter | Taip | Penerangan |
|-----------|------|-------------|
| ...$columns | tatasusunan | Nama lajur atau ungkapan |Pemulangan: self - Untuk rantaian kaedahContoh:
php// Simple selectQueryBuilder::table('users') ->select('id', 'username', 'email') ->get();
// Select with aliasesQueryBuilder::table('users') ->select('id as user_id', 'username as name') ->get();
// Select all columnsQueryBuilder::table('users') ->select('*') ->get();
// Select with expressionsQueryBuilder::table('orders') ->select('id', 'COUNT(*) as total_items') ->groupBy('id') ->get();di manaMenambah keadaan WHERE.
Section titled “di manaMenambah keadaan WHERE.”phppublic function where(string $column, string $operator = '=', mixed $value = null): selfParameter:| Parameter | Taip | Penerangan |
|-----------|------|-------------|
| $column | rentetan | Nama lajur |
| $operator | rentetan | Operator perbandingan |
| $value | bercampur | Nilai untuk dibandingkan |Pemulangan: self - Untuk rantaian kaedahPengusaha:| Operator | Penerangan | Contoh |
|----------|-------------|---------|
| = | Sama | ->where('status', '=', 'active') |
| != atau <> | Tidak sama | ->where('status', '!=', 'deleted') |
| > | Lebih besar daripada | ->where('price', '>', 100) |
| < | Kurang daripada | ->where('price', '<', 100) |
| >= | Lebih besar atau sama | ->where('age', '>=', 18) |
| <= | Kurang atau sama | ->where('age', '<=', 65) |
| LIKE | Padanan corak | ->where('name', 'LIKE', '%john%') |
| IN | Dalam senarai | ->where('status', 'IN', ['active', 'pending']) |
| NOT IN | Tiada dalam senarai | ->where('id', 'NOT IN', [1, 2, 3]) |
| BETWEEN | Julat | ->where('age', 'BETWEEN', [18, 65]) |
| IS NULL | Adakah batal | ->where('deleted_at', 'IS NULL') |
| IS NOT NULL | Bukan batal | ->where('deleted_at', 'IS NOT NULL') |Contoh:
php// Single conditionQueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->get();
// Multiple conditions (AND)QueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->where('age', '>=', 18) ->get();
// IN operatorQueryBuilder::table('products') ->select('*') ->where('category_id', 'IN', [1, 2, 3]) ->get();
// LIKE operatorQueryBuilder::table('users') ->select('*') ->where('email', 'LIKE', '%@example.com') ->get();
// NULL checkQueryBuilder::table('users') ->select('*') ->where('deleted_at', 'IS NULL') ->get();atau Di manaMenambah syarat ATAU.
Section titled “atau Di manaMenambah syarat ATAU.”phppublic function orWhere(string $column, string $operator = '=', mixed $value = null): selfContoh:
phpQueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->orWhere('premium', '=', 1) ->get(); // SELECT * FROM users WHERE status = 'active' OR premium = 1whereIn / whereNotInKaedah mudah untuk IN/NOT IN.
Section titled “whereIn / whereNotInKaedah mudah untuk IN/NOT IN.”phppublic function whereIn(string $column, array $values): selfpublic function whereNotIn(string $column, array $values): selfContoh:
phpQueryBuilder::table('posts') ->select('*') ->whereIn('status', ['published', 'scheduled']) ->get();
QueryBuilder::table('comments') ->select('*') ->whereNotIn('spam_score', [8, 9, 10]) ->get();whereNull / whereNotNullKaedah mudah untuk pemeriksaan NULL.
Section titled “whereNull / whereNotNullKaedah mudah untuk pemeriksaan NULL.”phppublic function whereNull(string $column): selfpublic function whereNotNull(string $column): selfContoh:
phpQueryBuilder::table('users') ->select('*') ->whereNotNull('verified_at') ->get();di mana AntaraMenyemak sama ada nilai berada di antara dua nilai.
Section titled “di mana AntaraMenyemak sama ada nilai berada di antara dua nilai.”phppublic function whereBetween(string $column, array $values): selfContoh:
phpQueryBuilder::table('products') ->select('*') ->whereBetween('price', [10, 100]) ->get();
QueryBuilder::table('orders') ->select('*') ->whereBetween('created_at', ['2024-01-01', '2024-12-31']) ->get();sertaiMenambah INNER JOIN.
Section titled “sertaiMenambah INNER JOIN.”phppublic function join( string $table, string $first, string $operator = '=', string $second = null): selfContoh:
phpQueryBuilder::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();kiriSertai / kananSertaiJenis gabungan alternatif.
Section titled “kiriSertai / kananSertaiJenis gabungan alternatif.”phppublic function leftJoin( string $table, string $first, string $operator = '=', string $second = null): self
public function rightJoin( string $table, string $first, string $operator = '=', string $second = null): selfContoh:
phpQueryBuilder::table('users') ->select('users.*', 'COUNT(posts.id) as post_count') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->groupBy('users.id') ->get();kumpulanOlehKumpulan keputusan mengikut lajur.
Section titled “kumpulanOlehKumpulan keputusan mengikut lajur.”phppublic function groupBy(...$columns): selfContoh:
phpQueryBuilder::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();mempunyaiMenambah keadaan HAVING.
Section titled “mempunyaiMenambah keadaan HAVING.”phppublic function having(string $column, string $operator = '=', mixed $value = null): selfContoh:
phpQueryBuilder::table('orders') ->select('user_id', 'COUNT(*) as order_count') ->groupBy('user_id') ->having('order_count', '>', 5) ->get();pesananOlehHasil pesanan.
Section titled “pesananOlehHasil pesanan.”phppublic function orderBy(string $column, string $direction = 'ASC'): selfParameter:| Parameter | Taip | Penerangan |
|-----------|------|-------------|
| $column | rentetan | Lajur untuk dipesan oleh |
| $direction | rentetan | ASC atau DESC |Contoh:
php// Single orderQueryBuilder::table('users') ->select('*') ->orderBy('created_at', 'DESC') ->get();
// Multiple ordersQueryBuilder::table('posts') ->select('*') ->orderBy('category_id', 'ASC') ->orderBy('created_at', 'DESC') ->get();
// Random orderQueryBuilder::table('quotes') ->select('*') ->orderBy('RAND()') ->get();had / offsetHad dan mengimbangi keputusan.
Section titled “had / offsetHad dan mengimbangi keputusan.”phppublic function limit(int $limit): selfpublic function offset(int $offset): selfContoh:
php// Simple limitQueryBuilder::table('posts') ->select('*') ->limit(10) ->get();
// Pagination$page = 2;$perPage = 20;$offset = ($page - 1) * $perPage;
QueryBuilder::table('posts') ->select('*') ->limit($perPage) ->offset($offset) ->get();Kaedah Pelaksanaan### dapatkanMelaksanakan pertanyaan dan mengembalikan semua hasil.
Section titled “Kaedah Pelaksanaan### dapatkanMelaksanakan pertanyaan dan mengembalikan semua hasil.”phppublic function get(): arrayPemulangan: array - Tatasusunan baris hasilContoh:
php$users = QueryBuilder::table('users') ->select('id', 'username', 'email') ->where('status', '=', 'active') ->orderBy('username') ->get();
foreach ($users as $user) { echo $user['username'] . ' (' . $user['email'] . ')' . "\n";}dahuluMendapat keputusan pertama.
Section titled “dahuluMendapat keputusan pertama.”phppublic function first(): ?arrayPemulangan: ?array - Baris pertama atau batalContoh:
php$user = QueryBuilder::table('users') ->select('*') ->where('id', '=', 123) ->first();
if ($user) { echo 'Found: ' . $user['username'];}terakhirMendapat keputusan terakhir.
Section titled “terakhirMendapat keputusan terakhir.”phppublic function last(): ?arrayContoh:
php$latestPost = QueryBuilder::table('posts') ->select('*') ->orderBy('created_at', 'DESC') ->last();kiraanMendapat kiraan keputusan.
Section titled “kiraanMendapat kiraan keputusan.”phppublic function count(): intPemulangan: int - Bilangan barisContoh:
php$activeUsers = QueryBuilder::table('users') ->where('status', '=', 'active') ->count();
echo "Active users: $activeUsers";wujudMenyemak sama ada pertanyaan mengembalikan sebarang hasil.
Section titled “wujudMenyemak sama ada pertanyaan mengembalikan sebarang hasil.”phppublic function exists(): boolPemulangan: bool - Benar jika keputusan wujudContoh:
phpif (QueryBuilder::table('users')->where('email', '=', 'test@example.com')->exists()) { echo 'User already exists';}agregatMendapat nilai agregat.
Section titled “agregatMendapat nilai agregat.”phppublic function aggregate(string $function, string $column): mixedContoh:
php$maxPrice = QueryBuilder::table('products') ->aggregate('MAX', 'price');
$avgAge = QueryBuilder::table('users') ->aggregate('AVG', 'age');
$totalSales = QueryBuilder::table('orders') ->aggregate('SUM', 'total');INSERT Pertanyaan### masukkanSisipkan baris.
Section titled “INSERT Pertanyaan### masukkanSisipkan baris.”phppublic function insert(array $values): boolContoh:
phpQueryBuilder::table('users')->insert([ 'username' => 'john', 'email' => 'john@example.com', 'password' => password_hash('secret', PASSWORD_BCRYPT), 'created_at' => date('Y-m-d H:i:s')]);masukkanBanyakMemasukkan berbilang baris.
Section titled “masukkanBanyakMemasukkan berbilang baris.”phppublic function insertMany(array $rows): boolContoh:
phpQueryBuilder::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()]]);UPDATE Pertanyaan### kemas kiniMengemas kini baris.
Section titled “UPDATE Pertanyaan### kemas kiniMengemas kini baris.”phppublic function update(array $values): intPemulangan: int - Bilangan baris yang terjejasContoh:
php// Update single userQueryBuilder::table('users') ->where('id', '=', 123) ->update([ 'email' => 'newemail@example.com', 'updated_at' => date('Y-m-d H:i:s') ]);
// Update multiple rowsQueryBuilder::table('posts') ->where('status', '=', 'draft') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->update([ 'status' => 'archived' ]);kenaikan / penurunanPenambahan atau pengurangan lajur.
Section titled “kenaikan / penurunanPenambahan atau pengurangan lajur.”phppublic function increment(string $column, int $amount = 1): intpublic function decrement(string $column, int $amount = 1): intContoh:
php// Increment view countQueryBuilder::table('posts') ->where('id', '=', 123) ->increment('views');
// Decrement stockQueryBuilder::table('products') ->where('id', '=', 456) ->decrement('stock', 5);DELETE Pertanyaan### padamMemadam baris.
Section titled “DELETE Pertanyaan### padamMemadam baris.”phppublic function delete(): intPemulangan: int - Bilangan baris yang dipadamkanContoh:
php// Delete single recordQueryBuilder::table('comments') ->where('id', '=', 789) ->delete();
// Delete multiple recordsQueryBuilder::table('log_entries') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->delete();potongMemadam semua baris daripada jadual.
Section titled “potongMemadam semua baris daripada jadual.”phppublic function truncate(): boolContoh:
php// Clear all sessionsQueryBuilder::table('sessions')->truncate();Ciri Lanjutan### Ungkapan Mentah
Section titled “Ciri Lanjutan### Ungkapan Mentah”phpQueryBuilder::table('products') ->select('id', 'name', QueryBuilder::raw('price * quantity as total')) ->get();Subqueries
Section titled “Subqueries”php$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();Mendapatkan SQL
Section titled “Mendapatkan SQL”phppublic function toSql(): stringContoh:
php$sql = QueryBuilder::table('users') ->select('id', 'username') ->where('status', '=', 'active') ->toSql();
echo $sql;// SELECT id, username FROM xoops_users WHERE status = ?Contoh Lengkap### Pilih Kompleks dengan Gabungan
Section titled “Contoh Lengkap### Pilih Kompleks dengan Gabungan”php<?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>';}Penomboran dengan QueryBuilder
Section titled “Penomboran dengan QueryBuilder”php<?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 resultsforeach ($articles as $article) { echo '<div class="article">' . htmlspecialchars($article['title']) . '</div>';}
// Display pagination linksif ($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>';}Analisis Data dengan Agregat
Section titled “Analisis Data dengan Agregat”php<?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);Amalan Terbaik1. Gunakan Pertanyaan Berparameter - QueryBuilder mengendalikan pengikatan parameter secara automatik
Section titled “Amalan Terbaik1. Gunakan Pertanyaan Berparameter - QueryBuilder mengendalikan pengikatan parameter secara automatik”- Kaedah Rantaian - Manfaatkan antara muka yang fasih untuk kod yang boleh dibaca
- Uji Output SQL - Gunakan
toSql()untuk mengesahkan pertanyaan yang dijana - Gunakan Indeks - Pastikan lajur yang kerap ditanya diindeks
- Had Keputusan - Sentiasa gunakan
limit()untuk set data yang besar - Gunakan Agregat - Biarkan pangkalan data melakukan counting/summing dan bukannya PHP
- Escape Output - Sentiasa melarikan data yang dipaparkan dengan
htmlspecialchars() - Prestasi Indeks - Pantau pertanyaan perlahan dan optimumkan dengan sewajarnya## Dokumentasi Berkaitan- XoopsDatabase - Lapisan pangkalan data dan sambungan
- Kriteria - Sistem pertanyaan berasaskan Kriteria Warisan
- ../Core/XoopsObject - Kegigihan objek data
- ../Module/Module-System - Operasi pangkalan data modul---
Lihat juga: API Pangkalan Data XOOPS