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

Discuz 風格 MySQL 查詢類封裝:dbQuery 核心原理解析與現代化重構建議

     編輯:MySQL 綜合教學

原始碼核心結構分析

該類封裝了 mysql_* 系列函數(已棄用),提供連線管理、查詢執行、結果集遍歷、錯誤處理等基礎功能,典型 Discuz/X 系列框架風格。

關鍵方法對照表

關鍵設計細節解讀

1. 字符集自動協商(4.1+)

if ($this->version() > '4.1') {
    global $dbcharset;
    if ($dbcharset) {
        mysql_query("SET character_set_connection=$dbcharset,
                          character_set_results=$dbcharset,
                          character_set_client=binary", $this->link);
    }
}

解決 character_set_client=binary 避免客戶端編碼干擾,connection/results 統一為應用字符集。

2. SQL_MODE 淨化(5.0.1+)

if ($this->version() > '5.0.1') {
    mysql_query("SET sql_mode=''", $this->link);
}

清空 SQL_MODE 避免 ONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES 等嚴格模式導致舊代碼報錯。

3. UNBUFFERED 查詢支援

$func = $type == 'UNBUFFERED' && function_exists('mysql_unbuffered_query')
    ? 'mysql_unbuffered_query' : 'mysql_query';

大結果集串流讀取,減少 PHP 記憶體佔用,但需一次性讀完才能執行下一條查詢。

現代化重構建議(PDO 版)

<?php
declare(strict_types=1);

class DbQuery {
    private PDO $pdo;
    private int $queryCount = 0;

    public function __construct(string $dsn, string $user, string $pass, array $options = []) {
        $defaultOptions = [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false,
            PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci",
        ];
        $this->pdo = new PDO($dsn, $user, $pass, $defaultOptions + $options);
    }

    public function query(string $sql, array $params = []): PDOStatement {
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute($params);
        $this->queryCount++;
        return $stmt;
    }

    public function fetchAll(string $sql, array $params = []): array {
        return $this->query($sql, $params)->fetchAll();
    }

    public function fetchOne(string $sql, array $params = []): ?array {
        return $this->query($sql, $params)->fetch() ?: null;
    }

    public function execute(string $sql, array $params = []): int {
        return $this->query($sql, $params)->rowCount();
    }

    public function lastInsertId(string $name = null): string {
        return $this->pdo->lastInsertId($name);
    }

    public function getQueryCount(): int {
        return $this->queryCount;
    }

    public function beginTransaction(): void {
        $this->pdo->beginTransaction();
    }

    public function commit(): void {
        $this->pdo->commit();
    }

    public function rollBack(): void {
        $this->pdo->rollBack();
    }

    public function getPdo(): PDO {
        return $this->pdo;
    }
}

遷移清單

方法功能對應 mysql_* 函數備註
__construct()建立連線、設定字符集、SQL_MODEmysql_connect/pconnect, mysql_select_db, mysql_query支援長連線 $pconnect
query()執行 SQL,支援 UNBUFFERED 模式mysql_query / mysql_unbuffered_query記錄查詢次數 $querynum
fetch_array()取關聯陣列mysql_fetch_array預設 MYSQL_ASSOC
num_rows()結果集行數mysql_num_rows-
affected_rows()影響行數mysql_affected_rows-
insert_id()自增 IDmysql_insert_id / LAST_INSERT_ID()兼容舊版回退
free_result()釋放資源mysql_free_result-
halt()錯誤輸出並退出-生產環境不可用
舊寫法新寫法優勢
$db->query($sql)$db->query($sql, $params)參數化防注入
$db->fetch_array($res)$stmt->fetch()物件導向、類型安全
$db->num_rows($res)$stmt->rowCount()統一介面
$db->insert_id()$db->lastInsertId()支援序列名
$db->halt()try/catch PDOException可控錯誤處理
mysql_unbuffered_queryPDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false現代 API

延伸閱讀

  • MySQL 查詢快取變量的相關解釋
  • MySQL 條件查詢語句的用法
  • 五種常用的 MySQL 命令列
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved