在 PHP 開發中,資料庫操作是核心環節之一。雖然現代框架多內建 ORM,但在輕量級專案或維護舊系統時,一個簡潔、功能完善的資料庫類別仍具備極高實用價值。本文將深入解析一個經典的 PHP MySQL 操作類別,涵蓋連線管理、CRUD 操作、欄位資訊獲取、錯誤處理等核心功能,並針對程式碼結構與潛在風險進行專業點評。
該類別採用傳統程序式風格封裝,核心屬性包含主機位址、資料庫名稱、使用者帳號、密碼、資料表前綴以及連線資源識別子。建構子支援陣列式配置注入,自動處理資料表前綴的底線補全,設計靈活便於多環境部署。
關鍵風險點: 程式碼全盤採用 mysql_* 系列函式,此擴展自 PHP 5.5 棄用、PHP 7.0 移除,生產環境嚴禁使用。所有 SQL 直接拼接變數,缺乏預處理機制,SQL 注入風險極高。
重構方向:
class Database {
private \PDO $pdo;
private string $prefix = '';
public function __construct(array $config) {
$dsn = "mysql:host={$config['host']};dbname={$config['name']};charset=utf8mb4";
$this->pdo = new \PDO($dsn, $config['user'], $config['pass'], [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_EMULATE_PREPARES => false,
]);
$this->prefix = rtrim($config['prefix'] ?? '', '_') . '_';
}
public function select(string $table, array $where = [], array $fields = ['*'], string $order = '', int $limit = 0, int $offset = 0): array {
$sql = "SELECT " . implode(', ', $fields) . " FROM `{$this->prefix}{$table}`";
$params = [];
if ($where) {
$conditions = [];
foreach ($where as $col => $val) {
$conditions[] = "`{$col}` = ?";
$params[] = $val;
}
$sql .= " WHERE " . implode(' AND ', $conditions);
}
if ($order) $sql .= " ORDER BY {$order}";
if ($limit) $sql .= " LIMIT {$limit}";
if ($offset) $sql .= " OFFSET {$offset}";
$stmt = $this->pdo->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}
// ... insert, update, delete 同理實作
}
此類別展示了早期 PHP 開發者對資料庫操作的深度封裝思維,功能覆蓋面廣、API 設計直觀。但受限於時代背景,其底層實作已嚴重落後現代安全標準。理解其設計精髓,結合 PDO 預處理、依賴注入、儲存庫模式等現代模式重構,才能打造出真正適用於當下生產環境的資料存取層。