فئة XoopsDatabase
توفر فئة XoopsDatabase طبقة تجريد قاعدة البيانات لـ XOOPS، وتتعامل مع إدارة الاتصال وتنفيذ الاستعلامات ومعالجة النتائج ومعالجة الأخطاء. وهي تدعم برامج تشغيل قواعد البيانات المتعددة من خلال معمارية برنامج التشغيل.
نظرة عامة على الفئة
Section titled “نظرة عامة على الفئة”namespace Xoops\Database;
abstract class XoopsDatabase{ protected $conn; protected $prefix; protected $logger;
abstract public function connect(bool $selectdb = true): bool; abstract public function query(string $sql, int $limit = 0, int $start = 0); abstract public function fetchArray($result): ?array; abstract public function fetchObject($result): ?object; abstract public function getRowsNum($result): int; abstract public function getAffectedRows(): int; abstract public function getInsertId(): int; abstract public function escape(string $string): string;}التسلسل الهرمي للفئة
Section titled “التسلسل الهرمي للفئة”XoopsDatabase (القاعدة المجردة)├── XoopsMySQLDatabase (MySQL Extension)│ └── XoopsMySQLDatabaseProxy (وكيل الأمان)└── XoopsMySQLiDatabase (MySQLi Extension) └── XoopsMySQLiDatabaseProxy (وكيل الأمان)
XoopsDatabaseFactory└── ينشئ مثيلات برنامج التشغيل المناسبالحصول على مثيل قاعدة البيانات
Section titled “الحصول على مثيل قاعدة البيانات”استخدام المصنع
Section titled “استخدام المصنع”// موصى به: استخدام المصنع$db = XoopsDatabaseFactory::getDatabaseConnection();استخدام getInstance
Section titled “استخدام getInstance”// البديل: الوصول المباشر إلى الفئة الفريدة$db = XoopsDatabase::getInstance();متغير عام
Section titled “متغير عام”// وراثي: استخدام متغير عامglobal $xoopsDB;الطرق الأساسية
Section titled “الطرق الأساسية”connect
Section titled “connect”إنشاء اتصال قاعدة البيانات.
abstract public function connect(bool $selectdb = true): boolالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$selectdb | bool | ما إذا كان يجب تحديد قاعدة البيانات |
الإرجاع: bool - صحيح عند الاتصال بنجاح
مثال:
$db = XoopsDatabaseFactory::getDatabaseConnection();if ($db->connect()) { echo "تم الاتصال بنجاح";}تنفيذ استعلام SQL.
abstract public function query( string $sql, int $limit = 0, int $start = 0): mixedالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$sql | string | سلسلة استعلام SQL |
$limit | int | أقصى عدد صفوف للإرجاع (0 = لا توجد حدود) |
$start | int | إزاحة البداية |
الإرجاع: resource|bool - موارد النتيجة أو خطأ في الفشل
مثال:
$db = XoopsDatabaseFactory::getDatabaseConnection();
// استعلام بسيط$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uid > 0";$result = $db->query($sql);
// الاستعلام مع الحد$sql = "SELECT * FROM " . $db->prefix('users');$result = $db->query($sql, 10, 0); // أول 10 صفوف
// الاستعلام مع الإزاحة$result = $db->query($sql, 10, 20); // 10 صفوف بدءاً من الصف 20queryF
Section titled “queryF”تنفيذ استعلام فرض العملية (يتجاوز فحوصات الأمان).
public function queryF(string $sql, int $limit = 0, int $start = 0): mixedحالات الاستخدام:
- عمليات INSERT و UPDATE و DELETE
- عندما تحتاج إلى تجاوز قيود القراءة فقط
مثال:
$sql = sprintf( "UPDATE %s SET views = views + 1 WHERE article_id = %d", $db->prefix('articles'), $articleId);$db->queryF($sql);prefix
Section titled “prefix”إضافة بادئة جدول قاعدة البيانات.
public function prefix(string $table = ''): stringالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$table | string | اسم الجدول بدون بادئة |
الإرجاع: string - اسم الجدول مع البادئة
مثال:
$db = XoopsDatabaseFactory::getDatabaseConnection();
echo $db->prefix('users'); // "xoops_users" (إذا كانت البادئة "xoops_")echo $db->prefix('modules'); // "xoops_modules"echo $db->prefix(); // "xoops_" (مجرد البادئة)fetchArray
Section titled “fetchArray”جلب صف النتيجة كمصفوفة ترابطية.
abstract public function fetchArray($result): ?arrayالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$result | resource | مورد نتيجة الاستعلام |
الإرجاع: array|null - مصفوفة ترابطية أو فارغ إذا لم تكن هناك صفوف أخرى
مثال:
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE level > 0";$result = $db->query($sql);
while ($row = $db->fetchArray($result)) { echo "المستخدم: " . $row['uname'] . "\n"; echo "البريد الإلكتروني: " . $row['email'] . "\n";}fetchObject
Section titled “fetchObject”جلب صف النتيجة كائن.
abstract public function fetchObject($result): ?objectالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$result | resource | مورد نتيجة الاستعلام |
الإرجاع: object|null - كائن به خصائص لكل عمود
مثال:
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uid = 1";$result = $db->query($sql);
if ($user = $db->fetchObject($result)) { echo "اسم المستخدم: " . $user->uname; echo "البريد الإلكتروني: " . $user->email;}fetchRow
Section titled “fetchRow”جلب صف النتيجة كمصفوفة رقمية.
abstract public function fetchRow($result): ?arrayمثال:
$sql = "SELECT uname, email FROM " . $db->prefix('users');$result = $db->query($sql);
while ($row = $db->fetchRow($result)) { echo "اسم المستخدم: " . $row[0] . ", البريد الإلكتروني: " . $row[1];}fetchBoth
Section titled “fetchBoth”جلب صف النتيجة كمصفوفة ترابطية وأيضاً رقمية.
abstract public function fetchBoth($result): ?arrayمثال:
$result = $db->query($sql);$row = $db->fetchBoth($result);echo $row['uname']; // بالاسمecho $row[0]; // بالفهرسgetRowsNum
Section titled “getRowsNum”الحصول على عدد الصفوف في مجموعة النتائج.
abstract public function getRowsNum($result): intالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$result | resource | مورد نتيجة الاستعلام |
الإرجاع: int - عدد الصفوف
مثال:
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE level > 0";$result = $db->query($sql);$count = $db->getRowsNum($result);echo "وجدت $count مستخدمين نشطين";getAffectedRows
Section titled “getAffectedRows”الحصول على عدد الصفوف المتأثرة من آخر استعلام.
abstract public function getAffectedRows(): intالإرجاع: int - عدد الصفوف المتأثرة
مثال:
$sql = "UPDATE " . $db->prefix('users') . " SET last_login = " . time() . " WHERE uid = 1";$db->queryF($sql);$affected = $db->getAffectedRows();echo "تم تحديث $affected صفوف";getInsertId
Section titled “getInsertId”الحصول على المعرف الذي تم إنشاؤه تلقائياً من آخر INSERT.
abstract public function getInsertId(): intالإرجاع: int - آخر معرف تم إدراجه
مثال:
$sql = sprintf( "INSERT INTO %s (title, content) VALUES (%s, %s)", $db->prefix('articles'), $db->quoteString($title), $db->quoteString($content));$db->queryF($sql);$newId = $db->getInsertId();echo "تم إنشاء المقالة برقم: $newId";escape
Section titled “escape”الهروب من سلسلة نصية للاستخدام الآمن في استعلامات SQL.
abstract public function escape(string $string): stringالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$string | string | سلسلة نصية للهروب |
الإرجاع: string - سلسلة نصية بالهروب (بدون علامات اقتباس)
مثال:
$unsafeInput = "O'Reilly";$safe = $db->escape($unsafeInput); // "O\'Reilly"
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uname = '" . $safe . "'";quoteString
Section titled “quoteString”الهروب واستقطاع سلسلة نصية لـ SQL.
public function quoteString(string $string): stringالمعاملات:
| المعامل | النوع | الوصف |
|---|---|---|
$string | string | سلسلة نصية للاستقطاع |
الإرجاع: string - سلسلة نصية بالهروب والاستقطاع
مثال:
$name = "John O'Connor";$quoted = $db->quoteString($name); // "'John O\'Connor'"
$sql = "INSERT INTO users (name) VALUES (" . $quoted . ")";freeRecordSet
Section titled “freeRecordSet”تحرير الذاكرة المرتبطة بالنتيجة.
abstract public function freeRecordSet($result): voidمثال:
$result = $db->query($sql);// معالجة النتائج...$db->freeRecordSet($result); // تحرير الذاكرةمعالجة الأخطاء
Section titled “معالجة الأخطاء”الحصول على آخر رسالة خطأ.
abstract public function error(): stringمثال:
$result = $db->query($sql);if (!$result) { echo "خطأ قاعدة البيانات: " . $db->error();}الحصول على آخر رقم خطأ.
abstract public function errno(): intمثال:
$result = $db->query($sql);if (!$result) { echo "الخطأ #" . $db->errno() . ": " . $db->error();}البيانات المحضرة (MySQLi)
Section titled “البيانات المحضرة (MySQLi)”يدعم برنامج التشغيل MySQLi البيانات المحضرة لتعزيز الأمان.
prepare
Section titled “prepare”إنشاء بيانات محضرة.
public function prepare(string $sql): mysqli_stmt|falseمثال:
$db = XoopsDatabaseFactory::getDatabaseConnection();
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uid = ?";$stmt = $db->prepare($sql);
$stmt->bind_param('i', $userId);$userId = 5;$stmt->execute();$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) { echo $row['uname'];}$stmt->close();البيانات المحضرة مع معاملات متعددة
Section titled “البيانات المحضرة مع معاملات متعددة”$sql = "INSERT INTO " . $db->prefix('articles') . " (title, content, author_id) VALUES (?, ?, ?)";$stmt = $db->prepare($sql);
$stmt->bind_param('ssi', $title, $content, $authorId);
$title = "مقالتي";$content = "محتوى المقالة هنا";$authorId = 1;
if ($stmt->execute()) { echo "تم إنشاء المقالة برقم: " . $stmt->insert_id;}
$stmt->close();دعم المعاملات
Section titled “دعم المعاملات”beginTransaction
Section titled “beginTransaction”بدء معاملة.
public function beginTransaction(): boolcommit
Section titled “commit”التزام المعاملة الحالية.
public function commit(): boolrollback
Section titled “rollback”التراجع عن المعاملة الحالية.
public function rollback(): boolمثال:
$db = XoopsDatabaseFactory::getDatabaseConnection();
try { $db->beginTransaction();
// عمليات متعددة $sql1 = "UPDATE " . $db->prefix('accounts') . " SET balance = balance - 100 WHERE id = 1"; $db->queryF($sql1);
$sql2 = "UPDATE " . $db->prefix('accounts') . " SET balance = balance + 100 WHERE id = 2"; $db->queryF($sql2);
// التحقق من الأخطاء if ($db->errno()) { throw new Exception($db->error()); }
$db->commit(); echo "اكتملت المعاملة";
} catch (Exception $e) { $db->rollback(); echo "فشلت المعاملة: " . $e->getMessage();}أمثلة الاستخدام الكاملة
Section titled “أمثلة الاستخدام الكاملة”عمليات CRUD الأساسية
Section titled “عمليات CRUD الأساسية”$db = XoopsDatabaseFactory::getDatabaseConnection();
// الإنشاء$sql = sprintf( "INSERT INTO %s (title, content, created) VALUES (%s, %s, %d)", $db->prefix('articles'), $db->quoteString('مقالة جديدة'), $db->quoteString('محتوى المقالة'), time());$db->queryF($sql);$articleId = $db->getInsertId();
// القراءة$sql = "SELECT * FROM " . $db->prefix('articles') . " WHERE id = " . (int)$articleId;$result = $db->query($sql);$article = $db->fetchArray($result);
// التحديث$sql = sprintf( "UPDATE %s SET title = %s, updated = %d WHERE id = %d", $db->prefix('articles'), $db->quoteString('عنوان محدّث'), time(), $articleId);$db->queryF($sql);
// الحذف$sql = "DELETE FROM " . $db->prefix('articles') . " WHERE id = " . (int)$articleId;$db->queryF($sql);استعلام الترقيم
Section titled “استعلام الترقيم”function getArticles(int $page = 1, int $perPage = 10): array{ $db = XoopsDatabaseFactory::getDatabaseConnection(); $start = ($page - 1) * $perPage;
// الحصول على العدد الإجمالي $sql = "SELECT COUNT(*) as total FROM " . $db->prefix('articles') . " WHERE published = 1"; $result = $db->query($sql); $row = $db->fetchArray($result); $total = $row['total'];
// احصل على صفحة من النتائج $sql = "SELECT * FROM " . $db->prefix('articles') . " WHERE published = 1 ORDER BY created DESC"; $result = $db->query($sql, $perPage, $start);
$articles = []; while ($row = $db->fetchArray($result)) { $articles[] = $row; }
return [ 'articles' => $articles, 'total' => $total, 'pages' => ceil($total / $perPage), 'current' => $page ];}البحث عن استعلام مع LIKE
Section titled “البحث عن استعلام مع LIKE”function searchArticles(string $keyword): array{ $db = XoopsDatabaseFactory::getDatabaseConnection();
$keyword = $db->escape($keyword); $sql = "SELECT * FROM " . $db->prefix('articles') . " WHERE title LIKE '%" . $keyword . "%'" . " OR content LIKE '%" . $keyword . "%'" . " ORDER BY created DESC";
$result = $db->query($sql, 50); // حد 50 نتيجة
$articles = []; while ($row = $db->fetchArray($result)) { $articles[] = $row; }
return $articles;}الانضمام إلى الاستعلام
Section titled “الانضمام إلى الاستعلام”function getArticlesWithAuthors(): array{ $db = XoopsDatabaseFactory::getDatabaseConnection();
$sql = "SELECT a.*, u.uname as author_name, u.email as author_email FROM " . $db->prefix('articles') . " a LEFT JOIN " . $db->prefix('users') . " u ON a.author_id = u.uid WHERE a.published = 1 ORDER BY a.created DESC";
$result = $db->query($sql, 20);
$articles = []; while ($row = $db->fetchArray($result)) { $articles[] = $row; }
return $articles;}فئة SqlUtility
Section titled “فئة SqlUtility”فئة مساعدة لعمليات ملف SQL.
splitMySqlFile
Section titled “splitMySqlFile”قسم ملف SQL إلى استعلامات فردية.
public static function splitMySqlFile(string $content): arrayمثال:
$sqlContent = file_get_contents('install.sql');$queries = SqlUtility::splitMySqlFile($sqlContent);
foreach ($queries as $query) { $db->queryF($query); if ($db->errno()) { echo "خطأ في التنفيذ: " . $query . "\n"; echo "الخطأ: " . $db->error() . "\n"; }}prefixQuery
Section titled “prefixQuery”استبدل عناصر نائبة للجدول بأسماء جداول البادئة.
public static function prefixQuery(string $sql, string $prefix): stringمثال:
$sql = "CREATE TABLE {PREFIX}_articles (id INT PRIMARY KEY)";$prefixedSql = SqlUtility::prefixQuery($sql, $db->prefix());// "CREATE TABLE xoops_articles (id INT PRIMARY KEY)"أفضل الممارسات
Section titled “أفضل الممارسات”الأمان
Section titled “الأمان”- الهروب دائماً من إدخال المستخدم:
$safe = $db->escape($_POST['input']);- استخدم البيانات المحضرة عند توفرها:
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");$stmt->bind_param('i', $id);- استخدم quoteString للقيم:
$sql = "INSERT INTO table (name) VALUES (" . $db->quoteString($name) . ")";الأداء
Section titled “الأداء”- استخدم دائماً LIMIT للجداول الكبيرة:
$result = $db->query($sql, 100); // حد النتائج- تحرير مجموعات النتائج عند الانتهاء:
$db->freeRecordSet($result);-
استخدم الفهارس المناسبة في تعريفات الجداول
-
فضل المعالجات على SQL الخام عند الإمكان
معالجة الأخطاء
Section titled “معالجة الأخطاء”- تحقق دائماً من الأخطاء:
$result = $db->query($sql);if (!$result) { trigger_error($db->error(), E_USER_WARNING);}- استخدم المعاملات للعمليات المترابطة المتعددة:
$db->beginTransaction();// ... عمليات ...$db->commit(); // أو $db->rollback();التوثيق ذي الصلة
Section titled “التوثيق ذي الصلة”- Criteria - نظام معايير الاستعلام
- QueryBuilder - بناء الاستعلام السلس
- ../Core/XoopsObjectHandler - استمرارية الكائن
انظر أيضاً: كود مصدر XOOPS