首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

Joomla 數據庫操作核心:JFactory::getDbo() 獲取連接、查詢構建、執行與結果集處理完整指南

     編輯:PHP 綜合知識

前言

JFactory::getDbo() 是 Joomla 獲取資料庫連接對象的標準入口(Joomla 4/5 為 Factory::getContainer()->get(DatabaseInterface::class))。返回的 JDatabaseDriver 實例封裝了查詢構建、預處理、事務、結果集遍歷等功能。本文系統講解連接獲取、查詢構建器、各類執行方式、結果集處理、錯誤處理及最佳實踐。

一、獲取資料庫對象

use Joomla\CMS\Factory;

// Joomla 3.x
$db = JFactory::getDbo();

// Joomla 4/5 (推薦)
$db = Factory::getContainer()->get(\Joomla\Database\DatabaseInterface::class);

// 別名(向後兼容層)
// $db = JFactory::getDbo();

二、查詢構建器(推薦方式)

使用 $db->getQuery(true) 獲取新的 JDatabaseQuery 實例,鏈式構建 SQL,自動處理表前綴(#__)、識別符轉義、參數綁定。

1. SELECT 查詢

$query = $db->getQuery(true)
    ->select($db->qn(['id', 'title', 'alias', 'created']))
    ->from($db->qn('#__content'))
    ->where($db->qn('state') . ' = 1')
    ->where($db->qn('catid') . ' IN (' . implode(',', array_map('intval', $catIds)) . ')')
    ->order($db->qn('created') . ' DESC')
    ->setLimit(20, 0);

$db->setQuery($query);

// 執行並獲取關聯陣列列表
$articles = $db->loadAssocList(); // [['id'=>1,'title'=>'...'], ...]

// 或獲取對象列表
$articles = $db->loadObjectList(); // [stdClass, ...]

// 單行單值
$count = $db->loadResult(); // 第一行第一列

// 單行對象
$article = $db->loadObject();

2. INSERT 插入

$columns = ['title', 'alias', 'catid', 'created', 'created_by', 'state'];
$values = [
    $db->q('My Article'),
    $db->q('my-article'),
    5,
    $db->q(date('Y-m-d H:i:s')),
    42,
    1,
];

$query = $db->getQuery(true)
    ->insert($db->qn('#__content'))
    ->columns($db->qn($columns))
    ->values(implode(',', $values));

$db->setQuery($query);
$db->execute();
$newId = $db->insertid(); // 獲取自增 ID

3. UPDATE 更新

$query = $db->getQuery(true)
    ->update($db->qn('#__content'))
    ->set([
        $db->qn('title') . ' = ' . $db->q('Updated Title'),
        $db->qn('modified') . ' = ' . $db->q(date('Y-m-d H:i:s')),
        $db->qn('modified_by') . ' = 42',
    ])
    ->where($db->qn('id') . ' = 123');

$db->setQuery($query);
$affected = $db->execute(); // 返回影響行數

4. DELETE 刪除

$query = $db->getQuery(true)
    ->delete($db->qn('#__content'))
    ->where($db->qn('id') . ' = 123');

$db->setQuery($query);
$affected = $db->execute();

三、預處理語句(防注入、批量執行)

// 準備語句
$query = $db->getQuery(true)
    ->select('*')
    ->from($db->qn('#__users'))
    ->where($db->qn('id') . ' = :id');

$db->setQuery($query);

// 綁定參數並執行多次
$stmt = $db->prepare($query);
$stmt->bindParam(':id', $id, \PDO::PARAM_INT);

foreach ([1, 2, 3, 4] as $id) {
    $stmt->execute();
    $user = $stmt->fetchObject();
    // 處理 $user
}

四、結果集處理方法總覽

方法返回類型適用場景
loadAssocList()array[] (關聯陣列)列表頁、API 返回 JSON
loadAssocList('key')array[key => row]需按主鍵快速查找
loadObjectList()stdClass[]習慣物件訪問屬性
loadObjectList('key')array[key => obj]同關聯陣列
loadRowList()array[] (數值索引)CSV 導出、矩陣運算
loadColumn()array (單列值)獲取 ID 列表、標籤列表
loadResult()mixed (單值)COUNT(*)、MAX(id) 等聚合
loadObject()stdClass|null單行記錄
loadAssoc()array|null單行關聯陣列
getNumRows()int影響/返回行數(SELECT 需先 execute)

五、事務控制

try {
    $db->transactionStart();

    $db->setQuery($insertQuery1)->execute();
    $db->setQuery($updateQuery2)->execute();
    $db->setQuery($deleteQuery3)->execute();

    $db->transactionCommit();
} catch (\Exception $e) {
    $db->transactionRollback();
    // 記錄日誌、拋出或返回錯誤
    throw new \RuntimeException('Database transaction failed: ' . $e->getMessage());
}

六、錯誤處理與調試

$db->setQuery($query);
if (!$db->execute()) {
    $errorNum = $db->getErrorNum();
    $errorMsg = $db->getErrorMsg();
    // 記錄日誌
    \Joomla\CMS\Log\Log::add("DB Error [$errorNum]: $errorMsg | SQL: " . $db->getQuery(), \Joomla\CMS\Log\Log::ERROR, 'database');
    return false;
}

// 調試:輸出最終 SQL(不執行)
echo $db->getQuery(); // 或 $query->__toString()

// 調試:替換參數後的完整 SQL(僅調試用,生產禁用)
echo $db->replacePrefix((string)$query);

七、常用工具方法

  • $db->quote($value) / $db->q($value):字串轉義加引號
  • $db->quoteName($name) / $db->qn($name):識別符轉義(反引號/雙引號/方括號)
  • $db->escape($string):僅轉義不加引號
  • $db->getPrefix():獲取表前綴(如 jos_)
  • $db->getVersion():資料庫服務器版本

八、最佳實踐清單

  1. 永遠使用查詢構建器/預處理,嚴禁手動拼接 SQL 字串。
  2. 表名統一用 #__ 前綴,由驅動自動替換為實際前綴。
  3. 識別符(表名、列名)用 qn(),數值用 q()。
  4. 大數據集分批處理:使用 setLimit() + 迴圈,避免記憶體溢出。
  5. 事務包裹多步寫入,保證原子性。
  6. 錯誤記錄含 SQL 與參數,便於排查(注意脫敏敏感字段)。
  7. Joomla 4/5 使用服務容器獲取 DB,便於單元測試 Mock。

九、從舊版 mysql_* 遷移對照表

舊寫法Joomla DBO 寫法
mysql_query($sql)$db->setQuery($sql)->execute()
mysql_fetch_assoc($res)$db->loadAssoc()
mysql_fetch_array($res)$db->loadRow() / $db->loadAssoc()
mysql_num_rows($res)$db->getNumRows()
mysql_insert_id()$db->insertid()
mysql_real_escape_string($v)$db->escape($v) / $db->q($v)

總結

掌握 JFactory::getDbo() 獲取連接、查詢構建器鏈式構建、預處理參數綁定、多樣結果集加載、事務控制與錯誤處理,即可在 Joomla 擴展中編寫安全、高效、可維護的資料庫操作代碼。遵循「構建器優先、參數綁定、前綴自動、事務保障」原則,拒絕裸 SQL 拼接,是專業 Joomla 開發者的基本功。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved