Lớp cơ sở dữ liệu Xoops
XoopsDatabase class cung cấp lớp trừu tượng hóa cơ sở dữ liệu cho XOOPS, xử lý quản lý kết nối, thực hiện truy vấn, xử lý kết quả và xử lý lỗi. Nó hỗ trợ nhiều trình điều khiển cơ sở dữ liệu thông qua kiến trúc trình điều khiển.
Tổng quan về lớp học
Phần tiêu đề “Tổng quan về lớp học”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;}Hệ thống phân cấp lớp
Phần tiêu đề “Hệ thống phân cấp lớp”XoopsDatabase (Abstract Base)├── XoopsMySQLDatabase (MySQL Extension)│ └── XoopsMySQLDatabaseProxy (Security Proxy)└── XoopsMySQLiDatabase (MySQLi Extension) └── XoopsMySQLiDatabaseProxy (Security Proxy)
XoopsDatabaseFactory└── Creates appropriate driver instancesLấy một phiên bản cơ sở dữ liệu
Phần tiêu đề “Lấy một phiên bản cơ sở dữ liệu”Sử dụng Nhà máy
Phần tiêu đề “Sử dụng Nhà máy”// Recommended: Use the factory$db = XoopsDatabaseFactory::getDatabaseConnection();Sử dụng getInstance
Phần tiêu đề “Sử dụng getInstance”// Alternative: Direct singleton access$db = XoopsDatabase::getInstance();Biến toàn cục
Phần tiêu đề “Biến toàn cục”// Legacy: Use global variableglobal $xoopsDB;Phương pháp cốt lõi
Phần tiêu đề “Phương pháp cốt lõi”kết nối
Phần tiêu đề “kết nối”Thiết lập kết nối cơ sở dữ liệu.
abstract public function connect(bool $selectdb = true): boolThông số:
| Tham số | Loại | Mô tả |
|---|---|---|
$selectdb | bool | Có nên chọn cơ sở dữ liệu |
Trả về: bool - Đúng khi kết nối thành công
Ví dụ:
$db = XoopsDatabaseFactory::getDatabaseConnection();if ($db->connect()) { echo "Connected successfully";}truy vấn
Phần tiêu đề “truy vấn”Thực hiện truy vấn SQL.
abstract public function query( string $sql, int $limit = 0, int $start = 0): mixedThông số:
| Tham số | Loại | Mô tả |
|---|---|---|
$sql | chuỗi | Chuỗi truy vấn SQL |
$limit | int | Số hàng tối đa cần trả về (0 = không giới hạn) |
$start | int | Bắt đầu bù đắp |
Trả về: resource|bool - Tài nguyên kết quả hoặc sai khi thất bại
Ví dụ:
$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 20truy vấnF
Phần tiêu đề “truy vấnF”Thực hiện truy vấn buộc thực hiện thao tác (bỏ qua kiểm tra bảo mật).
public function queryF(string $sql, int $limit = 0, int $start = 0): mixedTrường hợp sử dụng:
- Các thao tác CHÈN, CẬP NHẬT, XÓA
- Khi bạn cần bỏ qua các hạn chế chỉ đọc
Ví dụ:
$sql = sprintf( "UPDATE %s SET views = views + 1 WHERE article_id = %d", $db->prefix('articles'), $articleId);$db->queryF($sql);tiền tố ###
Thêm tiền tố bảng cơ sở dữ liệu.
public function prefix(string $table = ''): stringThông số:
| Tham số | Loại | Mô tả |
|---|---|---|
$table | chuỗi | Tên bảng không có tiền tố |
Trả về: string - Tên bảng có tiền tố
Ví dụ:
$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)tìm nạpArray
Phần tiêu đề “tìm nạpArray”Tìm nạp một hàng kết quả dưới dạng một mảng kết hợp.
abstract public function fetchArray($result): ?arrayThông số:
| Tham số | Loại | Mô tả |
|---|---|---|
$result | tài nguyên | Tài nguyên kết quả truy vấn |
Trả về: array|null - Mảng kết hợp hoặc null nếu không còn hàng
Ví dụ:
$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";}tìm nạpObject
Phần tiêu đề “tìm nạpObject”Lấy một hàng kết quả làm đối tượng.
abstract public function fetchObject($result): ?objectThông số:
| Tham số | Loại | Mô tả |
|---|---|---|
$result | tài nguyên | Tài nguyên kết quả truy vấn |
Trả về: object|null - Đối tượng có thuộc tính cho mỗi cột
Ví dụ:
$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;}tìm nạpRow
Phần tiêu đề “tìm nạpRow”Tìm nạp một hàng kết quả dưới dạng một mảng số.
abstract public function fetchRow($result): ?arrayVí dụ:
$sql = "SELECT uname, email FROM " . $db->prefix('users');$result = $db->query($sql);
while ($row = $db->fetchRow($result)) { echo "Username: " . $row[0] . ", Email: " . $row[1];}tìm nạpCả hai
Phần tiêu đề “tìm nạpCả hai”Tìm nạp một hàng kết quả dưới dạng cả mảng kết hợp và mảng số.
abstract public function fetchBoth($result): ?arrayVí dụ:
$result = $db->query($sql);$row = $db->fetchBoth($result);echo $row['uname']; // By nameecho $row[0]; // By indexgetRowsNum
Phần tiêu đề “getRowsNum”Lấy số hàng trong một tập kết quả.
abstract public function getRowsNum($result): intThông số:
| Tham số | Loại | Mô tả |
|---|---|---|
$result | tài nguyên | Tài nguyên kết quả truy vấn |
Trả về: int - Số lượng hàng
Ví dụ:
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE level > 0";$result = $db->query($sql);$count = $db->getRowsNum($result);echo "Found $count active users";getAffectedRows
Phần tiêu đề “getAffectedRows”Lấy số lượng hàng bị ảnh hưởng từ truy vấn cuối cùng.
abstract public function getAffectedRows(): intTrả về: int - Số lượng hàng bị ảnh hưởng
Ví dụ:
$sql = "UPDATE " . $db->prefix('users') . " SET last_login = " . time() . " WHERE uid = 1";$db->queryF($sql);$affected = $db->getAffectedRows();echo "Updated $affected rows";getInsertId
Phần tiêu đề “getInsertId”Lấy ID được tạo tự động từ INSERT cuối cùng.
abstract public function getInsertId(): int```**Trả về:** `int` - ID chèn cuối cùng
**Ví dụ:**```php$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";trốn thoát
Phần tiêu đề “trốn thoát”Thoát khỏi một chuỗi để sử dụng an toàn trong các truy vấn SQL.
abstract public function escape(string $string): stringThông số:
| Tham số | Loại | Mô tả |
|---|---|---|
$string | chuỗi | Chuỗi để thoát |
Trả về: string - Chuỗi thoát (không có dấu ngoặc kép)
Ví dụ:
$unsafeInput = "O'Reilly";$safe = $db->escape($unsafeInput); // "O\'Reilly"
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uname = '" . $safe . "'";quoteString
Phần tiêu đề “quoteString”Thoát và trích dẫn một chuỗi cho SQL.
public function quoteString(string $string): stringThông số:
| Tham số | Loại | Mô tả |
|---|---|---|
$string | chuỗi | Chuỗi để trích dẫn |
Trả về: string - Chuỗi thoát và trích dẫn
Ví dụ:
$name = "John O'Connor";$quoted = $db->quoteString($name); // "'John O\'Connor'"
$sql = "INSERT INTO users (name) VALUES (" . $quoted . ")";Bộ bản ghi miễn phí
Phần tiêu đề “Bộ bản ghi miễn phí”Giải phóng bộ nhớ liên quan đến kết quả.
abstract public function freeRecordSet($result): voidVí dụ:
$result = $db->query($sql);// Process results...$db->freeRecordSet($result); // Free memoryXử lý lỗi
Phần tiêu đề “Xử lý lỗi”lỗi ###
Nhận được thông báo lỗi cuối cùng.
abstract public function error(): stringVí dụ:
$result = $db->query($sql);if (!$result) { echo "Database error: " . $db->error();}không có lỗi
Phần tiêu đề “không có lỗi”Lấy số lỗi cuối cùng.
abstract public function errno(): intVí dụ:
$result = $db->query($sql);if (!$result) { echo "Error #" . $db->errno() . ": " . $db->error();}Báo cáo được chuẩn bị sẵn (MySQLi)
Phần tiêu đề “Báo cáo được chuẩn bị sẵn (MySQLi)”Trình điều khiển MySQLi hỗ trợ các câu lệnh đã chuẩn bị sẵn để tăng cường bảo mật.
chuẩn bị
Phần tiêu đề “chuẩn bị”Tạo một tuyên bố chuẩn bị.
public function prepare(string $sql): mysqli_stmt|falseVí dụ:
$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();Câu lệnh được chuẩn bị sẵn với nhiều tham số
Phần tiêu đề “Câu lệnh được chuẩn bị sẵn với nhiều tham số”$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();Hỗ trợ giao dịch
Phần tiêu đề “Hỗ trợ giao dịch”bắt đầuGiao dịch
Phần tiêu đề “bắt đầuGiao dịch”Bắt đầu một giao dịch.
public function beginTransaction(): boolcam kết
Phần tiêu đề “cam kết”Cam kết giao dịch hiện tại.
public function commit(): boolquay lại
Phần tiêu đề “quay lại”Khôi phục giao dịch hiện tại.
public function rollback(): boolVí dụ:
$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();}Ví dụ sử dụng hoàn chỉnh
Phần tiêu đề “Ví dụ sử dụng hoàn chỉnh”Hoạt động CRUD cơ bản
Phần tiêu đề “Hoạt động CRUD cơ bản”$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);Truy vấn phân trang
Phần tiêu đề “Truy vấn phân trang”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 ];}Truy vấn tìm kiếm với THÍCH
Phần tiêu đề “Truy vấn tìm kiếm với THÍCH”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;}Truy vấn tham gia
Phần tiêu đề “Truy vấn tham gia”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;}Lớp SqlUtility
Phần tiêu đề “Lớp SqlUtility”Trình trợ giúp class cho các thao tác với tệp SQL.
táchMySqlFile
Phần tiêu đề “táchMySqlFile”Chia tệp SQL thành các truy vấn riêng lẻ.
public static function splitMySqlFile(string $content): arrayVí dụ:
$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"; }}tiền tốTruy vấn
Phần tiêu đề “tiền tốTruy vấn”Thay thế phần giữ chỗ của bảng bằng tên bảng có tiền tố.
public static function prefixQuery(string $sql, string $prefix): stringVí dụ:
$sql = "CREATE TABLE {PREFIX}_articles (id INT PRIMARY KEY)";$prefixedSql = SqlUtility::prefixQuery($sql, $db->prefix());// "CREATE TABLE xoops_articles (id INT PRIMARY KEY)"Các phương pháp hay nhất
Phần tiêu đề “Các phương pháp hay nhất”Bảo mật
Phần tiêu đề “Bảo mật”- Luôn thoát khỏi thao tác nhập của người dùng:
$safe = $db->escape($_POST['input']);- Sử dụng các câu đã chuẩn bị sẵn nếu có:
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");$stmt->bind_param('i', $id);- Sử dụng quoteString cho các giá trị:
$sql = "INSERT INTO table (name) VALUES (" . $db->quoteString($name) . ")";Hiệu suất
Phần tiêu đề “Hiệu suất”- Luôn sử dụng LIMIT cho các bảng lớn:
$result = $db->query($sql, 100); // Limit results- Bộ kết quả miễn phí khi hoàn thành:
$db->freeRecordSet($result);-
Sử dụng các chỉ mục thích hợp trong định nghĩa bảng của bạn
-
Ưu tiên các trình xử lý hơn SQL thô khi có thể
Xử lý lỗi
Phần tiêu đề “Xử lý lỗi”- Luôn kiểm tra lỗi:
$result = $db->query($sql);if (!$result) { trigger_error($db->error(), E_USER_WARNING);}- Sử dụng giao dịch cho nhiều hoạt động liên quan:
$db->beginTransaction();// ... operations ...$db->commit(); // or $db->rollback();Tài liệu liên quan
Phần tiêu đề “Tài liệu liên quan”- Tiêu chí - Hệ thống tiêu chí truy vấn
- QueryBuilder - Xây dựng truy vấn thông thạo
- ../Core/XoopsObjectHandler - Tính bền vững của đối tượng
Xem thêm: Mã nguồn XOOPS