早期教學常見 mysql_connect、mysql_query 等函數,但 PHP 5.5 棄用、PHP 7.0 移除,現代專案嚴禁使用。
<?php
// ❌ 已移除的舊 API
$conn = mysql_connect("localhost", "root", "") or die("wrong!");
mysql_select_db("mydb", $conn);
$sql = "INSERT INTO `mydb`.`test` (`id`, `uid`, `regdate`, `remark`) VALUES ('', 'php200', now(), 'dddd')";
$que = mysql_query($sql, $conn);
echo $que ? "true" : "wrong";
?>
PDO 提供資料庫抽象層,支援預處理語句防止 SQL 注入,且可輕鬆切換資料庫驅動。
<?php
$dsn = 'mysql:host=localhost;dbname=mydb;charset=utf8mb4';
$user = 'root';
$pass = '';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 拋出例外
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // 關聯陣列
PDO::ATTR_EMULATE_PREPARES => false, // 使用原生預處理
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
error_log("資料庫連線失敗: " . $e->getMessage());
die("系統暫時無法使用,請稍後再試");
}
?>
<?php $sql = "INSERT INTO `test` (`uid`, `regdate`, `remark`) VALUES (?, NOW(), ?)"; $stmt = $pdo->prepare($sql); $stmt->execute(['php200', 'dddd']); echo "新增成功,ID: " . $pdo->lastInsertId(); ?>
<?php
// 單筆
$stmt = $pdo->prepare("SELECT * FROM `test` WHERE `uid` = ?");
$stmt->execute(['php200']);
$row = $stmt->fetch();
var_dump($row);
// 多筆
$stmt = $pdo->query("SELECT * FROM `test` ORDER BY `regdate` DESC LIMIT 10");
$rows = $stmt->fetchAll();
foreach ($rows as $row) {
echo "{$row['uid']} - {$row['remark']}<br>";
}
?>
<?php
try {
$pdo->beginTransaction();
$pdo->prepare("INSERT INTO `logs` (`msg`) VALUES (?)")->execute(['操作 A']);
$pdo->prepare("UPDATE `accounts` SET `balance` = `balance` - 100 WHERE `id` = 1")->execute();
$pdo->prepare("INSERT INTO `transactions` (`type`, `amount`) VALUES (?, ?)")->execute(['withdraw', 100]);
$pdo->commit();
echo "交易完成";
} catch (Exception $e) {
$pdo->rollBack();
error_log("交易失敗回滾: " . $e->getMessage());
throw $e;
}
?>
| 舊函數 | PDO 替代 | 備註 |
|---|---|---|
| mysql_connect | new PDO() | DSN 字串包含主機、資料庫、字元集 |
| mysql_query | $pdo->query() / $pdo->prepare()->execute() | 參數化查詢防注入 |
| mysql_fetch_array | $stmt->fetch(PDO::FETCH_ASSOC) | 預設模式可在連線選項設定 |
| mysql_real_escape_string | 不再需要 | 預處理自動處理逸出 |
| mysql_insert_id | $pdo->lastInsertId() | |
| mysql_error | $e->getMessage() | 捕獲 PDOException |
⚡ 效能提示:大量寫入時,單次交易包裹多條
execute()並最後commit(),可大幅提升吞吐量。