منشئ استعلام XOOPS
يوفر منشئ استعلام XOOPS واجهة حديثة وسلسة لبناء استعلامات SQL. يساعد في منع حقن SQL، ويحسن القراءة، ويوفر تجريد قاعدة بيانات لأنظمة قاعدة بيانات متعددة.
معمارية منشئ الاستعلام
Section titled “معمارية منشئ الاستعلام”graph TD A[QueryBuilder] -->|يبني| B[استعلامات SELECT] A -->|يبني| C[استعلامات INSERT] A -->|يبني| D[استعلامات UPDATE] A -->|يبني| E[استعلامات DELETE]
F[الجدول] -->|سلسلة| G[select] F -->|سلسلة| H[where] F -->|سلسلة| I[orderBy] F -->|سلسلة| J[limit]
G -->|سلسلة| K[join] G -->|سلسلة| H H -->|سلسلة| I I -->|سلسلة| J
L[طرق التنفيذ] -->|يرجع| M[النتائج] L -->|يرجع| N[العدد] L -->|يرجع| O[الأول/الأخير]فئة QueryBuilder
Section titled “فئة QueryBuilder”فئة منشئ الاستعلام الرئيسية مع واجهة سلسة.
نظرة عامة على الفئة
Section titled “نظرة عامة على الفئة”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 = [];}الطرق الثابتة
Section titled “الطرق الثابتة”إنشاء منشئ استعلام جديد لجدول.
public static function table(string $table): QueryBuilderالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$table | string | اسم الجدول (مع أو بدون بادئة) |
الإرجاع: QueryBuilder - مثيل منشئ الاستعلام
مثال:
$query = QueryBuilder::table('users');$query = QueryBuilder::table('xoops_users'); // مع البادئةاستعلامات SELECT
Section titled “استعلامات SELECT”select
Section titled “select”تحديد الأعمدة المراد تحديدها.
public function select(...$columns): selfالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
...$columns | array | أسماء الأعمدة أو التعبيرات |
الإرجاع: self - لربط الطريقة
مثال:
// اختيار بسيطQueryBuilder::table('users') ->select('id', 'username', 'email') ->get();
// تحديد مع الأسماء المستعارةQueryBuilder::table('users') ->select('id as user_id', 'username as name') ->get();
// اختر جميع الأعمدةQueryBuilder::table('users') ->select('*') ->get();
// التحديد مع التعبيراتQueryBuilder::table('orders') ->select('id', 'COUNT(*) as total_items') ->groupBy('id') ->get();إضافة شرط WHERE.
public function where(string $column, string $operator = '=', mixed $value = null): selfالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$column | string | اسم العمود |
$operator | string | عامل المقارنة |
$value | mixed | القيمة للمقارنة |
الإرجاع: self - لربط الطريقة
العوامل:
| العامل | الوصف | مثال |
|---|---|---|
= | يساوي | ->where('status', '=', 'active') |
!= أو <> | لا يساوي | ->where('status', '!=', 'deleted') |
> | أكبر من | ->where('price', '>', 100) |
< | أقل من | ->where('price', '<', 100) |
>= | أكبر أو يساوي | ->where('age', '>=', 18) |
<= | أقل أو يساوي | ->where('age', '<=', 65) |
LIKE | مطابقة النمط | ->where('name', 'LIKE', '%john%') |
IN | في القائمة | ->where('status', 'IN', ['active', 'pending']) |
NOT IN | ليس في القائمة | ->where('id', 'NOT IN', [1, 2, 3]) |
BETWEEN | النطاق | ->where('age', 'BETWEEN', [18, 65]) |
IS NULL | هو فارغ | ->where('deleted_at', 'IS NULL') |
IS NOT NULL | ليس فارغ | ->where('deleted_at', 'IS NOT NULL') |
مثال:
// شرط واحدQueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->get();
// شروط متعددة (AND)QueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->where('age', '>=', 18) ->get();
// عامل INQueryBuilder::table('products') ->select('*') ->where('category_id', 'IN', [1, 2, 3]) ->get();
// عامل LIKEQueryBuilder::table('users') ->select('*') ->where('email', 'LIKE', '%@example.com') ->get();
// فحص NULLQueryBuilder::table('users') ->select('*') ->where('deleted_at', 'IS NULL') ->get();orWhere
Section titled “orWhere”إضافة شرط OR.
public function orWhere(string $column, string $operator = '=', mixed $value = null): selfمثال:
QueryBuilder::table('users') ->select('*') ->where('status', '=', 'active') ->orWhere('premium', '=', 1) ->get(); // SELECT * FROM users WHERE status = 'active' OR premium = 1whereIn / whereNotIn
Section titled “whereIn / whereNotIn”طرق الراحة لـ IN/NOT IN.
public function whereIn(string $column, array $values): selfpublic function whereNotIn(string $column, array $values): selfمثال:
QueryBuilder::table('posts') ->select('*') ->whereIn('status', ['published', 'scheduled']) ->get();
QueryBuilder::table('comments') ->select('*') ->whereNotIn('spam_score', [8, 9, 10]) ->get();whereNull / whereNotNull
Section titled “whereNull / whereNotNull”طرق الراحة للفحص الفارغ.
public function whereNull(string $column): selfpublic function whereNotNull(string $column): selfمثال:
QueryBuilder::table('users') ->select('*') ->whereNotNull('verified_at') ->get();whereBetween
Section titled “whereBetween”التحقق من ما إذا كانت القيمة بين قيمتين.
public function whereBetween(string $column, array $values): selfمثال:
QueryBuilder::table('products') ->select('*') ->whereBetween('price', [10, 100]) ->get();
QueryBuilder::table('orders') ->select('*') ->whereBetween('created_at', ['2024-01-01', '2024-12-31']) ->get();إضافة INNER JOIN.
public function join( string $table, string $first, string $operator = '=', string $second = null): selfمثال:
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();leftJoin / rightJoin
Section titled “leftJoin / rightJoin”أنواع ربط بديلة.
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مثال:
QueryBuilder::table('users') ->select('users.*', 'COUNT(posts.id) as post_count') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->groupBy('users.id') ->get();groupBy
Section titled “groupBy”تجميع النتائج حسب العمود (الأعمدة).
public function groupBy(...$columns): selfمثال:
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();having
Section titled “having”إضافة شرط HAVING.
public function having(string $column, string $operator = '=', mixed $value = null): selfمثال:
QueryBuilder::table('orders') ->select('user_id', 'COUNT(*) as order_count') ->groupBy('user_id') ->having('order_count', '>', 5) ->get();orderBy
Section titled “orderBy”ترتيب النتائج.
public function orderBy(string $column, string $direction = 'ASC'): selfالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$column | string | العمود المراد الترتيب حسبه |
$direction | string | ASC أو DESC |
مثال:
// ترتيب واحدQueryBuilder::table('users') ->select('*') ->orderBy('created_at', 'DESC') ->get();
// ترتيب متعددQueryBuilder::table('posts') ->select('*') ->orderBy('category_id', 'ASC') ->orderBy('created_at', 'DESC') ->get();
// ترتيب عشوائيQueryBuilder::table('quotes') ->select('*') ->orderBy('RAND()') ->get();limit / offset
Section titled “limit / offset”حد وإزاحة النتائج.
public function limit(int $limit): selfpublic function offset(int $offset): selfمثال:
// حد بسيطQueryBuilder::table('posts') ->select('*') ->limit(10) ->get();
// الترقيم$page = 2;$perPage = 20;$offset = ($page - 1) * $perPage;
QueryBuilder::table('posts') ->select('*') ->limit($perPage) ->offset($offset) ->get();طرق التنفيذ
Section titled “طرق التنفيذ”تنفيذ الاستعلام وإرجاع جميع النتائج.
public function get(): arrayالإرجاع: array - مصفوفة صفوف النتائج
مثال:
$users = QueryBuilder::table('users') ->select('id', 'username', 'email') ->where('status', '=', 'active') ->orderBy('username') ->get();
foreach ($users as $user) { echo $user['username'] . ' (' . $user['email'] . ')' . "\n";}الحصول على النتيجة الأولى.
public function first(): ?arrayالإرجاع: ?array - الصف الأول أو فارغ
مثال:
$user = QueryBuilder::table('users') ->select('*') ->where('id', '=', 123) ->first();
if ($user) { echo 'وجد: ' . $user['username'];}الحصول على النتيجة الأخيرة.
public function last(): ?arrayمثال:
$latestPost = QueryBuilder::table('posts') ->select('*') ->orderBy('created_at', 'DESC') ->last();الحصول على عدد النتائج.
public function count(): intالإرجاع: int - عدد الصفوف
مثال:
$activeUsers = QueryBuilder::table('users') ->where('status', '=', 'active') ->count();
echo "المستخدمون النشطون: $activeUsers";exists
Section titled “exists”التحقق من عودة الاستعلام إلى أي نتائج.
public function exists(): boolالإرجاع: bool - صحيح إذا كانت النتائج موجودة
مثال:
if (QueryBuilder::table('users')->where('email', '=', 'test@example.com')->exists()) { echo 'المستخدم موجود بالفعل';}aggregate
Section titled “aggregate”الحصول على قيم التجميع.
public function aggregate(string $function, string $column): mixedمثال:
$maxPrice = QueryBuilder::table('products') ->aggregate('MAX', 'price');
$avgAge = QueryBuilder::table('users') ->aggregate('AVG', 'age');
$totalSales = QueryBuilder::table('orders') ->aggregate('SUM', 'total');استعلامات INSERT
Section titled “استعلامات INSERT”insert
Section titled “insert”إدراج صف.
public function insert(array $values): boolمثال:
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')]);insertMany
Section titled “insertMany”إدراج صفوف متعددة.
public function insertMany(array $rows): boolمثال:
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()]]);استعلامات UPDATE
Section titled “استعلامات UPDATE”update
Section titled “update”تحديث الصفوف.
public function update(array $values): intالإرجاع: int - عدد الصفوف المتأثرة
مثال:
// تحديث مستخدم واحدQueryBuilder::table('users') ->where('id', '=', 123) ->update([ 'email' => 'newemail@example.com', 'updated_at' => date('Y-m-d H:i:s') ]);
// تحديث صفوف متعددةQueryBuilder::table('posts') ->where('status', '=', 'draft') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->update([ 'status' => 'archived' ]);increment / decrement
Section titled “increment / decrement”زيادة أو تناقص العمود.
public function increment(string $column, int $amount = 1): intpublic function decrement(string $column, int $amount = 1): intمثال:
// زيادة عدد المشاهداتQueryBuilder::table('posts') ->where('id', '=', 123) ->increment('views');
// تقليل المخزونQueryBuilder::table('products') ->where('id', '=', 456) ->decrement('stock', 5);استعلامات DELETE
Section titled “استعلامات DELETE”delete
Section titled “delete”حذف الصفوف.
public function delete(): intالإرجاع: int - عدد الصفوف المحذوفة
مثال:
// حذف سجل واحدQueryBuilder::table('comments') ->where('id', '=', 789) ->delete();
// حذف سجلات متعددةQueryBuilder::table('log_entries') ->where('created_at', '<', date('Y-m-d', strtotime('-30 days'))) ->delete();truncate
Section titled “truncate”حذف جميع الصفوف من الجدول.
public function truncate(): boolمثال:
// مسح جميع الجلساتQueryBuilder::table('sessions')->truncate();الميزات المتقدمة
Section titled “الميزات المتقدمة”تعبيرات خام
Section titled “تعبيرات خام”QueryBuilder::table('products') ->select('id', 'name', QueryBuilder::raw('price * quantity as total')) ->get();استعلامات فرعية
Section titled “استعلامات فرعية”$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();الحصول على SQL
Section titled “الحصول على SQL”public function toSql(): stringمثال:
$sql = QueryBuilder::table('users') ->select('id', 'username') ->where('status', '=', 'active') ->toSql();
echo $sql;// SELECT id, username FROM xoops_users WHERE status = ?أمثلة كاملة
Section titled “أمثلة كاملة”تحديد معقد مع الربط
Section titled “تحديد معقد مع الربط”<?php/** * الحصول على المشاركات مع معلومات المؤلف والفئة */
$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">بقلم ' . htmlspecialchars($post['author']) . ' في ' . htmlspecialchars($post['category']) . '</p>'; echo '<p>' . htmlspecialchars($post['content']) . '</p>'; echo '</article>';}الترقيم مع QueryBuilder
Section titled “الترقيم مع QueryBuilder”<?php/** * نتائج مقسمة إلى صفحات */
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;$perPage = 20;$offset = ($page - 1) * $perPage;
// الحصول على العدد الإجمالي$total = QueryBuilder::table('articles') ->where('status', '=', 'published') ->count();
// احصل على نتائج الصفحة$articles = QueryBuilder::table('articles') ->select('*') ->where('status', '=', 'published') ->orderBy('created_at', 'DESC') ->limit($perPage) ->offset($offset) ->get();
// حساب الترقيم$pages = ceil($total / $perPage);
// عرض النتائجforeach ($articles as $article) { echo '<div class="article">' . htmlspecialchars($article['title']) . '</div>';}
// عرض روابط الترقيم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>';}تحليل البيانات مع التجميعات
Section titled “تحليل البيانات مع التجميعات”<?php/** * تحليل المبيعات */
// إجمالي المبيعات حسب المنطقة$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";}
// متوسط قيمة الطلب$avgOrderValue = QueryBuilder::table('orders') ->aggregate('AVG', 'total');
echo 'متوسط قيمة الطلب: $' . number_format($avgOrderValue, 2);أفضل الممارسات
Section titled “أفضل الممارسات”- استخدم الاستعلامات ذات المعاملات - يتعامل QueryBuilder مع ربط المعاملات تلقائياً
- ربط الطرق - استفد من الواجهة السلسة للحصول على كود قابل للقراءة
- اختبر إخراج SQL - استخدم
toSql()للتحقق من الاستعلامات المولدة - استخدم الفهارس - تأكد من أن الأعمدة المستعلم عنها بكثرة لديها فهارس
- حد النتائج - دائماً استخدم
limit()لمجموعات البيانات الكبيرة - استخدم التجميعات - اترك قاعدة البيانات تقوم بالعد والجمع بدلاً من PHP
- الهروب من الإخراج - دائماً هرب البيانات المعروضة باستخدام
htmlspecialchars() - أداء الفهرس - راقب الاستعلامات البطيئة وحسنها وفقاً لذلك
التوثيق ذي الصلة
Section titled “التوثيق ذي الصلة”- XoopsDatabase - طبقة قاعدة البيانات والاتصالات
- Criteria - نظام الاستعلام القديم القائم على Criteria
- ../Core/XoopsObject - استمرارية كائن البيانات
- ../Module/Module-System - عمليات قاعدة بيانات الوحدة
انظر أيضاً: واجهة برمجية قاعدة بيانات XOOPS