原文使用的 mysql_connect、mysql_query 等函數 自 PHP 5.5 棄用、PHP 7.0 完全移除。現代專案請改用 mysqli (程序/物件風格) 或 PDO (資料庫抽象層),並搭配預處理語句防止 SQL 注入。
db_connect.php<?php
// db_connect.php
$host = 'localhost';
$user = 'root';
$pass = 'your_password';
$dbname = 'mythroad';
$charset = 'utf8mb4';
$mysqli = new mysqli($host, $user, $pass, $dbname);
if ($mysqli->connect_errno) {
// 正式環境請記錄日誌而非直接輸出
die('資料庫連線失敗: ' . $mysqli->connect_error);
}
$mysqli->set_charset($charset);
// 可選:設定錯誤模式為例外
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
return $mysqli; // 若被 include 直接回傳物件
<?php
// insert_user.php
require_once 'db_connect.php';
$uname = $_POST['username'] ?? '';
$pwd = $_POST['password'] ?? '';
// 1. 準備 SQL (佔位符 ?)
$stmt = $mysqli->prepare("INSERT INTO mythroad (username, password) VALUES (?, ?)");
// 2. 綁定參數 (s = string, i = integer, d = double, b = blob)
$stmt->bind_param('ss', $uname, password_hash($pwd, PASSWORD_DEFAULT));
// 3. 執行
if ($stmt->execute()) {
echo "註冊成功,ID: " . $stmt->insert_id;
} else {
error_log("Insert failed: " . $stmt->error);
echo "註冊失敗,請稍後再試";
}
$stmt->close();
$mysqli->close();
<?php
// update_email.php
require_once 'db_connect.php';
$username = '小明';
$newEmail = 'xiaoming@163.com';
$stmt = $mysqli->prepare("UPDATE user SET email = ? WHERE username = ?");
$stmt->bind_param('ss', $newEmail, $username);
if ($stmt->execute()) {
echo "更新成功,影響行數: " . $stmt->affected_rows;
} else {
echo "更新失敗: " . $stmt->error;
}
$stmt->close();
<?php
// pdo_connect.php
$dsn = "mysql:host=localhost;dbname=mythroad;charset=utf8mb4";
$user = 'root';
$pass = 'your_password';
$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("PDO Connection failed: " . $e->getMessage());
die('資料庫連線失敗');
}
return $pdo;
<?php
// pdo_insert.php
require_once 'pdo_connect.php';
$uname = $_POST['username'] ?? '';
$pwd = $_POST['password'] ?? '';
$sql = "INSERT INTO mythroad (username, password) VALUES (?, ?)";
$stmt = $pdo->prepare($sql);
$stmt->execute([$uname, password_hash($pwd, PASSWORD_DEFAULT)]);
echo "新增成功,ID: " . $pdo->lastInsertId();
| 舊寫法 (高風險) | 現代寫法 (安全) | 說明 |
|---|---|---|
mysql_query("INSERT ... VALUES ('$var')") | $stmt->execute([$var]) | 參數化查詢,徹底分離代碼與資料 |
md5($pwd) | password_hash($pwd, PASSWORD_DEFAULT) | bcrypt/argon2 自動加鹽、可調成本 |
mysql_real_escape_string() | 不需要 (預處理自動處理) | 預處理在協議層分離參數 |
mysql_connect | new mysqli / new PDO | 支援預處理、事務、多重查詢 |
<?php
require_once 'pdo_connect.php';
try {
$pdo->beginTransaction();
// 扣款
$stmt = $pdo->prepare("UPDATE accounts SET balance = balance - ? WHERE user_id = ?");
$stmt->execute([100, 1]);
// 入帳
$stmt = $pdo->prepare("UPDATE accounts SET balance = balance + ? WHERE user_id = ?");
$stmt->execute([100, 2]);
$pdo->commit();
echo "轉帳成功";
} catch (Exception $e) {
$pdo->rollBack();
echo "轉帳失敗: " . $e->getMessage();
}
utf8mb4_unicode_ci (支援 emoji)mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT) 或 PDO ERRMODE_EXCEPTION採用 mysqli/PDO + 預處理語句 + password_hash,即可建立安全、可維護、相容未來版本的 PHP 資料庫應用。