DAO (Data Access Object) 模式將資料存取邏輯與業務邏輯分離。透過一個統一介面封裝 CRUD 操作,上層呼叫者無需關心 SQL 細節、資料庫類型或連線管理。
query()、execute() 方法。addUser()、getUserById())。<?php
class BaseDao {
private $db;
public function __construct(array $config) {
// 建議改用 PDO,此處為示範保留 mysql_*
$this->db = mysql_connect($config['host'], $config['user'], $config['pass']);
mysql_select_db($config['database'], $this->db);
mysql_set_charset('utf8', $this->db);
}
public function query(string $sql) {
return mysql_query($sql, $this->db);
}
public function fetchAll(string $sql): array {
$res = $this->query($sql);
$rows = [];
while ($row = mysql_fetch_assoc($res)) {
$rows[] = $row;
}
mysql_free_result($res);
return $rows;
}
}
<?php
require_once 'BaseDao.php';
class UserDao extends BaseDao {
public function addUser(string $username): bool {
$sql = sprintf(
"INSERT INTO `user` (`username`) VALUES ('%s')",
mysql_real_escape_string($username, $this->db)
);
return (bool) $this->query($sql);
}
public function getUserById(int $id): ?array {
$sql = sprintf("SELECT * FROM `user` WHERE `id` = %d", $id);
$rows = $this->fetchAll($sql);
return $rows[0] ?? null;
}
}
$config = [
'host' => 'localhost',
'user' => 'root',
'pass' => 'password',
'database' => 'myapp'
];
$userDao = new UserDao($config);
$userDao->addUser('initphp');
$user = $userDao->getUserById(1);
var_dump($user);
interface UserDaoInterface {
public function addUser(string $username): bool;
public function getUserById(int $id): ?array;
}
class PdoUserDao implements UserDaoInterface {
private $pdo;
public function __construct(PDO $pdo) { $this->pdo = $pdo; }
// 使用預處理語句實作...
}
| 優點 | 缺點 |
|---|---|
| 資料存取邏輯集中,易維護、易測試 | 簡單專案可能過度設計,增加類別數量 |
| 支援多資料庫切換(MySQL/PostgreSQL/SQLite) | 複雜查詢(多表 JOIN、動態 WHERE)仍需寫 SQL |
| 業務層不依賴具體資料庫實作 | 若無 ORM,手寫映射代碼繁瑣 |
中大型專案建議直接採用 Eloquent (Laravel)、Doctrine ORM 或 Cycle ORM,享受關聯映射、遷移、查詢建構器等完整功能,避免重複造輪子。