| 方法 | 功能 | 對應 mysql_* 函數 | 備註 |
__construct() | 建立連線、設定字符集、SQL_MODE | mysql_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() | 自增 ID | mysql_insert_id / LAST_INSERT_ID() | 兼容舊版回退 |
free_result() | 釋放資源 | mysql_free_result | - |
halt() | 錯誤輸出並退出 | - | 生產環境不可用 |
關鍵設計細節解讀
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;
}
}
遷移清單
| 舊寫法 | 新寫法 | 優勢 |
$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_query | PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false | 現代 API |
延伸閱讀
- MySQL 查詢快取變量的相關解釋
- MySQL 條件查詢語句的用法
- 五種常用的 MySQL 命令列
- 上一篇文章: MySQL 查詢優化器工作原理深度解析:索引選擇、常數折疊、EXPLAIN 實戰
- 下一篇文章: MySQL Query Cache 深度調優指南:配置參數、狀態監控、碎片治理
Copyright ©
程式碼之家 All Rights Reserved