דלגו לתוכן

XoopsDatabase Class

המחלקה XoopsDatabase מספקת שכבת הפשטת מסד נתונים עבור XOOPS, טיפול בניהול חיבורים, ביצוע שאילתות, עיבוד תוצאות וטיפול בשגיאות. הוא תומך במספר מנהלי התקנים של מסד נתונים באמצעות ארכיטקטורת מנהלי התקנים.

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;
}
XoopsDatabase (Abstract Base)
├── XoopsMySQLDatabase (MySQL Extension)
│ └── XoopsMySQLDatabaseProxy (Security Proxy)
└── XoopsMySQLiDatabase (MySQLi Extension)
└── XoopsMySQLiDatabaseProxy (Security Proxy)
XoopsDatabaseFactory
└── Creates appropriate driver instances
// Recommended: Use the factory
$db = XoopsDatabaseFactory::getDatabaseConnection();
// Alternative: Direct singleton access
$db = XoopsDatabase::getInstance();
// Legacy: Use global variable
global $xoopsDB;

יוצר חיבור למסד נתונים.

abstract public function connect(bool $selectdb = true): bool

פרמטרים:

פרמטרהקלדתיאור
$selectdbboolהאם לבחור את מסד הנתונים

מחזירות: bool - נכון בחיבור מוצלח

דוגמה:

$db = XoopsDatabaseFactory::getDatabaseConnection();
if ($db->connect()) {
echo "Connected successfully";
}

מבצע שאילתת SQL.

abstract public function query(
string $sql,
int $limit = 0,
int $start = 0
): mixed

פרמטרים:

פרמטרהקלדתיאור
$sqlמחרוזתמחרוזת שאילתה SQL
$limitintמקסימום שורות להחזרה (0 = ללא הגבלה)
$startintקיזוז התחלתי

החזרות: resource|bool - משאב תוצאה או שקר בכשל

דוגמה:

$db = XoopsDatabaseFactory::getDatabaseConnection();
// Simple query
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uid > 0";
$result = $db->query($sql);
// Query with limit
$sql = "SELECT * FROM " . $db->prefix('users');
$result = $db->query($sql, 10, 0); // First 10 rows
// Query with offset
$result = $db->query($sql, 10, 20); // 10 rows starting at row 20

מבצע שאילתה מאלצת את הפעולה (עוקף בדיקות אבטחה).

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

מקדים את קידומת טבלת מסד הנתונים.

public function prefix(string $table = ''): string

פרמטרים:

פרמטרהקלדתיאור
$tableמחרוזתשם טבלה ללא קידומת

החזרות: string - שם טבלה עם קידומת

דוגמה:

$db = XoopsDatabaseFactory::getDatabaseConnection();
echo $db->prefix('users'); // "xoops_users" (if prefix is "xoops_")
echo $db->prefix('modules'); // "xoops_modules"
echo $db->prefix(); // "xoops_" (just the prefix)

מביא שורת תוצאה כמערך אסוציאטיבי.

abstract public function fetchArray($result): ?array

פרמטרים:

פרמטרהקלדתיאור
$resultמשאבמשאב תוצאות שאילתה

החזרות: array|null - מערך אסוציאטיבי או null אם אין יותר שורות

דוגמה:

$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE level > 0";
$result = $db->query($sql);
while ($row = $db->fetchArray($result)) {
echo "User: " . $row['uname'] . "\n";
echo "Email: " . $row['email'] . "\n";
}

מביא שורת תוצאה כאובייקט.

abstract public function fetchObject($result): ?object

פרמטרים:

פרמטרהקלדתיאור
$resultמשאבמשאב תוצאות שאילתה

החזרות: object|null - אובייקט עם מאפיינים עבור כל עמודה

דוגמה:

$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uid = 1";
$result = $db->query($sql);
if ($user = $db->fetchObject($result)) {
echo "Username: " . $user->uname;
echo "Email: " . $user->email;
}

מביא שורת תוצאה כמערך מספרי.

abstract public function fetchRow($result): ?array

דוּגמָה:

$sql = "SELECT uname, email FROM " . $db->prefix('users');
$result = $db->query($sql);
while ($row = $db->fetchRow($result)) {
echo "Username: " . $row[0] . ", Email: " . $row[1];
}

מביא שורת תוצאה כמערך אסוציאטיבי וגם כמערך מספרי.

abstract public function fetchBoth($result): ?array

דוּגמָה:

$result = $db->query($sql);
$row = $db->fetchBoth($result);
echo $row['uname']; // By name
echo $row[0]; // By index

מקבל את מספר השורות בערכת תוצאות.

abstract public function getRowsNum($result): int

פרמטרים:

פרמטרהקלדתיאור
$resultמשאבמשאב תוצאות שאילתה

החזרות: int - מספר שורות

דוגמה:

$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE level > 0";
$result = $db->query($sql);
$count = $db->getRowsNum($result);
echo "Found $count active users";

מקבל את מספר השורות המושפעות מהשאילתה האחרונה.

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 "Updated $affected rows";

מקבל את המזהה שנוצר אוטומטית מה-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 "Created article with ID: $newId";

בורחת מחרוזת לשימוש בטוח בשאילתות SQL.

abstract public function escape(string $string): string

פרמטרים:

פרמטרהקלדתיאור
$stringמחרוזתמחרוזת לברוח

החזרות: string - מחרוזת בריחה (ללא מרכאות)

דוגמה:

$unsafeInput = "O'Reilly";
$safe = $db->escape($unsafeInput); // "O\'Reilly"
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uname = '" . $safe . "'";

בורח ומצטט מחרוזת עבור SQL.

public function quoteString(string $string): string

פרמטרים:

פרמטרהקלדתיאור
$stringמחרוזתמחרוזת לצטט

החזרות: string - מחרוזת בריחה ומצוטטת

דוגמה:

$name = "John O'Connor";
$quoted = $db->quoteString($name); // "'John O\'Connor'"
$sql = "INSERT INTO users (name) VALUES (" . $quoted . ")";

משחרר זיכרון הקשור לתוצאה.

abstract public function freeRecordSet($result): void

דוּגמָה:

$result = $db->query($sql);
// Process results...
$db->freeRecordSet($result); // Free memory

מקבל את הודעת השגיאה האחרונה.

abstract public function error(): string

דוּגמָה:

$result = $db->query($sql);
if (!$result) {
echo "Database error: " . $db->error();
}

מקבל את מספר השגיאה האחרון.

abstract public function errno(): int

דוּגמָה:

$result = $db->query($sql);
if (!$result) {
echo "Error #" . $db->errno() . ": " . $db->error();
}

מנהל ההתקן MySQLi תומך בהצהרות מוכנות לאבטחה משופרת.

יוצר הצהרה מוכנה.

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 = "My Article";
$content = "Article content here";
$authorId = 1;
if ($stmt->execute()) {
echo "Article created with ID: " . $stmt->insert_id;
}
$stmt->close();

מתחיל עסקה.

public function beginTransaction(): bool

מחייב את העסקה הנוכחית.

public function commit(): bool

מחזיר את העסקה הנוכחית לאחור.

public function rollback(): bool

דוּגמָה:

$db = XoopsDatabaseFactory::getDatabaseConnection();
try {
$db->beginTransaction();
// Multiple operations
$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);
// Check for errors
if ($db->errno()) {
throw new Exception($db->error());
}
$db->commit();
echo "Transaction completed";
} catch (Exception $e) {
$db->rollback();
echo "Transaction failed: " . $e->getMessage();
}

$db = XoopsDatabaseFactory::getDatabaseConnection();
// CREATE
$sql = sprintf(
"INSERT INTO %s (title, content, created) VALUES (%s, %s, %d)",
$db->prefix('articles'),
$db->quoteString('New Article'),
$db->quoteString('Article content'),
time()
);
$db->queryF($sql);
$articleId = $db->getInsertId();
// READ
$sql = "SELECT * FROM " . $db->prefix('articles') . " WHERE id = " . (int)$articleId;
$result = $db->query($sql);
$article = $db->fetchArray($result);
// UPDATE
$sql = sprintf(
"UPDATE %s SET title = %s, updated = %d WHERE id = %d",
$db->prefix('articles'),
$db->quoteString('Updated Title'),
time(),
$articleId
);
$db->queryF($sql);
// DELETE
$sql = "DELETE FROM " . $db->prefix('articles') . " WHERE id = " . (int)$articleId;
$db->queryF($sql);
function getArticles(int $page = 1, int $perPage = 10): array
{
$db = XoopsDatabaseFactory::getDatabaseConnection();
$start = ($page - 1) * $perPage;
// Get total count
$sql = "SELECT COUNT(*) as total FROM " . $db->prefix('articles') . " WHERE published = 1";
$result = $db->query($sql);
$row = $db->fetchArray($result);
$total = $row['total'];
// Get page of results
$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
];
}
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); // Limit to 50 results
$articles = [];
while ($row = $db->fetchArray($result)) {
$articles[] = $row;
}
return $articles;
}
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;
}

מחלקה עוזרת עבור פעולות קבצים SQL.

מפצל קובץ 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 "Error executing: " . $query . "\n";
echo "Error: " . $db->error() . "\n";
}
}

מחליף את מצייני המיקום של הטבלה בשמות טבלה עם קידומת.

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)"

  1. הימנע תמיד מקלט משתמש:
$safe = $db->escape($_POST['input']);
  1. השתמש בהצהרות מוכנות כאשר הן זמינות:
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
$stmt->bind_param('i', $id);
  1. השתמש ב-quoteString עבור ערכים:
$sql = "INSERT INTO table (name) VALUES (" . $db->quoteString($name) . ")";
  1. השתמש תמיד ב-LIMIT עבור שולחנות גדולים:
$result = $db->query($sql, 100); // Limit results
  1. ערכות תוצאות חינמיות בסיום:
$db->freeRecordSet($result);
  1. השתמש באינדקסים מתאימים בהגדרות הטבלה שלך

  2. העדיפו את המטפלים על פני SQL הגולמי במידת האפשר

  1. בדוק תמיד אם יש שגיאות:
$result = $db->query($sql);
if (!$result) {
trigger_error($db->error(), E_USER_WARNING);
}
  1. השתמש בעסקאות למספר פעולות קשורות:
$db->beginTransaction();
// ... operations ...
$db->commit(); // or $db->rollback();
  • קריטריונים - מערכת קריטריוני שאילתה
  • QueryBuilder - בניית שאילתות שוטפת
  • ../Core/XoopsObjectHandler - התמדה של אובייקט

ראה גם: קוד מקור XOOPS