คลาสฐานข้อมูล Xoops
คลาส 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();การใช้ getInstance
หัวข้อที่มีชื่อว่า “การใช้ getInstance”// Alternative: Direct singleton access$db = XoopsDatabase::getInstance();ตัวแปรร่วม
หัวข้อที่มีชื่อว่า “ตัวแปรร่วม”// Legacy: Use global variableglobal $xoopsDB;วิธีการหลัก
หัวข้อที่มีชื่อว่า “วิธีการหลัก”เชื่อมต่อ
หัวข้อที่มีชื่อว่า “เชื่อมต่อ”สร้างการเชื่อมต่อฐานข้อมูล
abstract public function connect(bool $selectdb = true): boolพารามิเตอร์:
| พารามิเตอร์ | พิมพ์ | คำอธิบาย |
|---|---|---|
$selectdb | บูล | ไม่ว่าจะเลือกฐานข้อมูล |
ผลตอบแทน: 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 สตริงการสืบค้น |
$limit | อินท์ | แถวสูงสุดที่จะส่งคืน (0 = ไม่มีขีดจำกัด) |
$start | อินท์ | เริ่มต้นออฟเซ็ต |
ผลตอบแทน: 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แบบสอบถามF
หัวข้อที่มีชื่อว่า “แบบสอบถามF”ดำเนินการค้นหาที่บังคับให้ดำเนินการ (ข้ามการตรวจสอบความปลอดภัย)
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)fetchArray
หัวข้อที่มีชื่อว่า “fetchArray”ดึงข้อมูลแถวผลลัพธ์เป็นอาร์เรย์ที่เชื่อมโยง
abstract public function fetchArray($result): ?arrayพารามิเตอร์:
| พารามิเตอร์ | พิมพ์ | คำอธิบาย |
|---|---|---|
$result | ทรัพยากร | ทรัพยากรผลลัพธ์แบบสอบถาม |
ผลตอบแทน: array|null - Associative array หรือ 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 nameecho $row[0]; // By indexgetRowsNum
หัวข้อที่มีชื่อว่า “getRowsNum”รับจำนวนแถวในชุดผลลัพธ์
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";getInsertId
หัวข้อที่มีชื่อว่า “getInsertId”รับ ID ที่สร้างขึ้นอัตโนมัติจาก INSERT สุดท้าย
abstract public function getInsertId(): intผลตอบแทน: int - การแทรกครั้งสุดท้าย ID
ตัวอย่าง:
$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 - สตริงที่ใช้ Escape (ไม่มีเครื่องหมายคำพูด)
ตัวอย่าง:
$unsafeInput = "O'Reilly";$safe = $db->escape($unsafeInput); // "O\'Reilly"
$sql = "SELECT * FROM " . $db->prefix('users') . " WHERE uname = '" . $safe . "'";quoteString
หัวข้อที่มีชื่อว่า “quoteString”Escape และใส่เครื่องหมายคำพูดสตริงสำหรับ SQL
public function quoteString(string $string): stringพารามิเตอร์:
| พารามิเตอร์ | พิมพ์ | คำอธิบาย |
|---|---|---|
$string | สตริง | สตริงที่จะอ้างอิง |
ผลตอบแทน: string - สตริงที่ใช้ Escape และเครื่องหมายคำพูด
ตัวอย่าง:
$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)
หัวข้อที่มีชื่อว่า “คำสั่งที่เตรียมไว้ (MySQLi)”ไดรเวอร์ 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();คำสั่งที่เตรียมไว้พร้อมพารามิเตอร์หลายตัว
หัวข้อที่มีชื่อว่า “คำสั่งที่เตรียมไว้พร้อมพารามิเตอร์หลายตัว”$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();}ตัวอย่างการใช้งานที่สมบูรณ์
หัวข้อที่มีชื่อว่า “ตัวอย่างการใช้งานที่สมบูรณ์”การดำเนินงานขั้นพื้นฐาน CRUD
หัวข้อที่มีชื่อว่า “การดำเนินงานขั้นพื้นฐาน CRUD”$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 ];}ข้อความค้นหาด้วย LIKE
หัวข้อที่มีชื่อว่า “ข้อความค้นหาด้วย 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); // 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;}คลาส SqlUtility
หัวข้อที่มีชื่อว่า “คลาส SqlUtility”คลาสตัวช่วยสำหรับการดำเนินการกับไฟล์ SQL
แยกไฟล์ MySqlFile
หัวข้อที่มีชื่อว่า “แยกไฟล์ MySqlFile”แยกไฟล์ 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)"แนวทางปฏิบัติที่ดีที่สุด
หัวข้อที่มีชื่อว่า “แนวทางปฏิบัติที่ดีที่สุด”ความปลอดภัย
หัวข้อที่มีชื่อว่า “ความปลอดภัย”- หลีกเลี่ยงอินพุตของผู้ใช้เสมอ:
$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) . ")";ประสิทธิภาพ
หัวข้อที่มีชื่อว่า “ประสิทธิภาพ”- ใช้ LIMIT เสมอสำหรับตารางขนาดใหญ่:
$result = $db->query($sql, 100); // Limit results- ชุดผลลัพธ์ฟรีเมื่อเสร็จสิ้น:
$db->freeRecordSet($result);-
ใช้ดัชนีที่เหมาะสม ในคำจำกัดความของตารางของคุณ
-
ต้องการตัวจัดการมากกว่า raw SQL เมื่อเป็นไปได้
การจัดการข้อผิดพลาด
หัวข้อที่มีชื่อว่า “การจัดการข้อผิดพลาด”- ตรวจสอบข้อผิดพลาดเสมอ:
$result = $db->query($sql);if (!$result) { trigger_error($db->error(), E_USER_WARNING);}- ใช้ธุรกรรมสำหรับการดำเนินการที่เกี่ยวข้องหลายอย่าง:
$db->beginTransaction();// ... operations ...$db->commit(); // or $db->rollback();เอกสารที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “เอกสารที่เกี่ยวข้อง”- เกณฑ์ - ระบบเกณฑ์การค้นหา
- QueryBuilder - การสร้างแบบสอบถามอย่างคล่องแคล่ว
- ../Core/XoopsObjectHandler - การคงอยู่ของวัตถุ
ดูเพิ่มเติมที่: ¤XOOPS Source Code