三大擴展對比
| 特性 | mysql (已移除) | mysqli | PDO |
| PHP 版本 | ≤ 5.6(7.0 移除) | 5.0+ 內建 | 5.1+ 內建 |
| API 風格 | 程序式 | 程序式 + 物件導向 | 物件導向 |
| 預處理語句 | ❌ | ✅ | ✅ |
| 多重查詢 | ❌ | ✅ (multi_query) | ❌ (需模擬) |
| 事務支援 | ❌ | ✅ | ✅ |
| 資料庫抽象 | ❌ 仅 MySQL | ❌ 仅 MySQL | ✅ 12+ 驅動 |
| 效能 | 基準 | 略優於 PDO(原生) | 略低(抽象層) |
| 持久連線 | mysql_pconnect | mysqli::persistent / p: 前綴 | PDO::ATTR_PERSISTENT |
mysqli 物件導向範例
$mysqli = new mysqli('localhost', 'user', 'pass', 'db');
if ($mysqli->connect_errno) die('Connect failed: '.$mysqli->connect_error);
$stmt = $mysqli->prepare('SELECT id, name FROM users WHERE email = ?');
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->bind_result($id, $name);
while ($stmt->fetch()) {
echo "$id: $name\n";
}
$stmt->close();
$mysqli->close();
PDO 範例(推薦新專案)
$pdo = new PDO('mysql:host=localhost;dbname=db;charset=utf8mb4', 'user', 'pass', [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // 真實預處理
]);
$stmt = $pdo->prepare('SELECT id, name FROM users WHERE email = ?');
$stmt->execute([$email]);
while ($row = $stmt->fetch()) {
echo "{$row['id']}: {$row['name']}\n";
}
常見坑點
mysqli_query($link, $sql) 參數順序:連線在前;mysql_query($sql, $link) 連線在後(可省略)。
mysqli 不支援 mysql_* 函數,遷移需逐行改寫。
- Windows
php.ini 需啟用 extension=mysqli、extension=pdo_mysql;Linux 編譯參數 --with-mysqli --with-pdo-mysql。
- 字元集:連線後執行
SET NAMES utf8mb4 或 DSN 加 charset=utf8mb4。
選型建議
- 新專案:優先 PDO,資料庫可攜性、現代 API、框架(Laravel/Symfony/ThinkPHP)皆以 PDO 為基礎。
- 純 MySQL、追求極致效能、需 multi_query:mysqli 物件導向模式。
- 維護舊專案:逐步重構至 PDO/mysqli,勿再用
mysql_*。