第十三章-PHP與MySQL
一,連接數據庫
1. 使用 MySQLi(面向對象方式)
<?php
// 數據庫參數
$host = 'localhost';
$username = 'root';
$password = '';
$database = 'test_db';// 創建連接
$conn = new mysqli($host, $username, $password, $database);// 檢查連接是否成功
if ($conn->connect_error) {die("連接失敗: " . $conn->connect_error);
}echo "數據庫連接成功!";// 執行查詢示例
$sql = "SELECT id, name FROM users";
$result = $conn->query($sql);if ($result->num_rows > 0) {while ($row = $result->fetch_assoc()) {echo "ID: " . $row["id"] . ",姓名: " . $row["name"];}
} else {echo "沒有查詢到數據";
}// 關閉連接
$conn->close();
?>
2. 使用 MySQLi(過程化方式)
<?php
$host = 'localhost';
$username = 'root';
$password = '';
$database = 'test_db';// 創建連接
$conn = mysqli_connect($host, $username, $password, $database);// 檢查連接
if (!$conn) {die("連接失敗: " . mysqli_connect_error());
}echo "數據庫連接成功!";// 執行查詢示例
$sql = "SELECT id, name FROM users";
$result = mysqli_query($conn, $sql);if (mysqli_num_rows($result) > 0) {while ($row = mysqli_fetch_assoc($result)) {echo "ID: " . $row["id"] . ",姓名: " . $row["name"];}
}// 關閉連接
mysqli_close($conn);
?>
3. 使用 PDO(支持多種數據庫)
<?php
$host = 'localhost';
$database = 'test_db';
$username = 'root';
$password = '';try {// 創建 PDO 連接$conn = new PDO("mysql:host=$host;dbname=$database", $username, $password);// 設置錯誤模式為異常捕獲$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);echo "數據庫連接成功!";// 執行查詢示例(使用預處理語句防注入)$sql = "SELECT id, name FROM users";$stmt = $conn->prepare($sql);$stmt->execute();// 獲取結果$result = $stmt->fetchAll(PDO::FETCH_ASSOC);foreach ($result as $row) {echo "ID: " . $row["id"] . ",姓名: " . $row["name"];}} catch (PDOException $e) {die("連接失敗: " . $e->getMessage());
}// 關閉連接(PDO 自動管理)
$conn = null;
?>
關鍵注意事項
-
防止 SQL 注入
-
使用預處理語句(如
$stmt->prepare()
+bindParam
或execute([參數])
)。 -
示例(PDO 預處理):
$stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (:name, :email)"); $stmt->bindParam(':name', $name); $stmt->bindParam(':email', $email); $stmt->execute();
-
-
錯誤處理
- MySQLi 使用
$conn->connect_error
或mysqli_connect_error()
。 - PDO 使用異常捕獲(
try...catch
+setAttribute
)。
- MySQLi 使用
-
關閉連接
- MySQLi:
$conn->close()
或mysqli_close($conn)
。 - PDO:
$conn = null
。
- MySQLi:
常見問題
-
連接失敗可能原因
- 用戶名/密碼錯誤
- 數據庫未啟動
- 防火墻阻止連接
- PHP 未啟用 MySQLi/PDO 擴展(檢查
php.ini
)
-
啟用擴展
在php.ini
中取消注釋:;extension=mysqli ;extension=pdo_mysql
重啟 Web 服務器生效。
二、增刪改查操作實現
1. 增加數據(Create)
MySQLi 預處理插入
// 準備預處理語句
$stmt = $conn->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->bind_param("ss", $name, $email); // "ss" 表示兩個字符串參數// 設置參數并執行
$name = "張三";
$email = "zhangsan@example.com";
$stmt->execute();echo "插入成功,ID: " . $stmt->insert_id;
$stmt->close();
PDO 預處理插入
try {$sql = "INSERT INTO users (name, email) VALUES (:name, :email)";$stmt = $conn->prepare($sql);// 綁定參數并執行$stmt->execute([':name' => '李四',':email' => 'lisi@example.com']);echo "插入成功,ID: " . $conn->lastInsertId();
} catch (PDOException $e) {echo "錯誤: " . $e->getMessage();
}
2. 查詢數據(Read)
MySQLi 查詢并遍歷結果
$sql = "SELECT id, name, email FROM users";
$result = $conn->query($sql);if ($result->num_rows > 0) {while ($row = $result->fetch_assoc()) {echo "ID: {$row['id']}, 姓名: {$row['name']}, 郵箱: {$row['email']}<br>";}
} else {echo "沒有數據";
}
$result->free(); // 釋放結果集
PDO 查詢并遍歷結果
try {$stmt = $conn->query("SELECT id, name, email FROM users");$results = $stmt->fetchAll(PDO::FETCH_ASSOC);foreach ($results as $row) {echo "ID: {$row['id']}, 姓名: {$row['name']}, 郵箱: {$row['email']}<br>";}
} catch (PDOException $e) {echo "錯誤: " . $e->getMessage();
}
3. 更新數據(Update)
MySQLi 預處理更新
$stmt = $conn->prepare("UPDATE users SET email = ? WHERE id = ?");
$stmt->bind_param("si", $email, $id); // "si" 表示字符串和整數$email = "new_email@example.com";
$id = 1;
$stmt->execute();echo "更新了 {$stmt->affected_rows} 條記錄";
$stmt->close();
PDO 預處理更新
try {$sql = "UPDATE users SET email = :email WHERE id = :id";$stmt = $conn->prepare($sql);$stmt->execute([':email' => 'updated@example.com',':id' => 1]);echo "更新了 {$stmt->rowCount()} 條記錄";
} catch (PDOException $e) {echo "錯誤: " . $e->getMessage();
}
4. 刪除數據(Delete)
MySQLi 預處理刪除
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $id); // "i" 表示整數$id = 2;
$stmt->execute();echo "刪除了 {$stmt->affected_rows} 條記錄";
$stmt->close();
PDO 預處理刪除
try {$sql = "DELETE FROM users WHERE id = :id";$stmt = $conn->prepare($sql);$stmt->execute([':id' => 3]);echo "刪除了 {$stmt->rowCount()} 條記錄";
} catch (PDOException $e) {echo "錯誤: " . $e->getMessage();
}
5.安全與最佳實踐
-
始終使用預處理語句
- 避免 SQL 注入攻擊,禁止直接拼接用戶輸入到 SQL 中。
-
錯誤處理
- MySQLi 檢查
$conn->error
,PDO 使用try...catch
捕獲異常。
- MySQLi 檢查
-
關閉連接
// MySQLi $conn->close();// PDO $conn = null;
-
驗證輸入數據
- 使用
filter_var()
驗證郵箱、URL 等格式。 - 檢查數值范圍(如
$id > 0
)。
- 使用
6.完整流程圖
1. 連接數據庫 → 2. 準備SQL語句 → 3. 綁定參數 → 4. 執行操作 → 5. 處理結果 → 6. 關閉連接
7.擴展建議
-
使用 ORM 框架
如 Laravel 的 Eloquent 或 Doctrine,簡化數據庫操作。 -
事務處理
對于多個關聯操作,使用事務保證數據一致性:// PDO 事務示例 $conn->beginTransaction(); try {$conn->exec("UPDATE account SET balance = balance - 100 WHERE id = 1");$conn->exec("UPDATE account SET balance = balance + 100 WHERE id = 2");$conn->commit(); } catch (Exception $e) {$conn->rollBack();echo "事務失敗: " . $e->getMessage(); }
三,網站查詢操作
一,OOP 寫法
OOP(面向對象編程,Object-Oriented Programming) 是一種程序設計思想和方法,它把數據和對數據的操作組織成對象(Object),通過對象之間的交互來完成程序設計。
OOP 的核心概念
- 類(Class)
- 類是對象的藍圖或模板,定義了對象的屬性(數據)**和**方法(操作)。
- 比如:“狗”可以是一個類,它有顏色、品種這些屬性,還有叫、跑這些方法。
- 對象(Object)
- 對象是類的實例,是具體存在的個體。
- 比如:“小黑”是一只狗,它是“狗”類的一個對象。
- 封裝(Encapsulation)
- 把數據和操作數據的方法打包在一起,對外隱藏內部細節,只暴露必要的接口。
- 好處是保護數據安全,減少外部干擾。
- 繼承(Inheritance)
- 子類可以繼承父類的屬性和方法,復用代碼,還可以擴展或修改已有功能。
- 比如,“哈士奇”類可以繼承“狗”類的基本特性,再加上自己的特性。
- 多態(Polymorphism)
- 同一種方法在不同對象上可以有不同表現。
- 比如,不同動物的“叫”方法,狗叫“汪汪”,貓叫“喵喵”,但都可以統一調用“叫”這個動作。
$mysqli = new mysqli('localhost', 'dbuser', 'dbpass', 'dbname');
if ($mysqli->connect_errno) {throw new Exception('數據庫連接失敗:' . $mysqli->connect_error);
}
$mysqli->set_charset('utf8mb4');$sql = "SELECT id, username, email FROM users WHERE status = 1 AND is_deleted = 0 ORDER BY created_at DESC LIMIT 10";
$result = $mysqli->query($sql);if (!$result) {throw new Exception('查詢失敗:' . $mysqli->error);
}$data = [];
while ($row = $result->fetch_assoc()) {$data[] = $row;
}
$result->free();// 返回數據
return $data;
- 必須判斷連接和查詢是否成功
- 必須釋放結果集
- 查詢多行,循環
fetch_assoc()
拼到數組里 - 查詢限制條件齊全:
WHERE
、ORDER BY
、LIMIT
都要標準化
二、參數化查詢(防SQL注入)
生產環境絕對禁止拼接變量,必須用預處理。
示例:按用戶名模糊搜索
$stmt = $mysqli->prepare("SELECT id, username, email FROM users WHERE username LIKE CONCAT('%', ?, '%') AND status = 1 LIMIT 20");
if (!$stmt) {throw new Exception('預處理失敗:' . $mysqli->error);
}$keyword = 'alice'; // 搜索關鍵詞
$stmt->bind_param('s', $keyword);
$stmt->execute();$result = $stmt->get_result();
$data = [];
while ($row = $result->fetch_assoc()) {$data[] = $row;
}
$stmt->close();return $data;
- 預處理 (
prepare
+bind_param
) 必須使用 - 模糊搜索需要
CONCAT('%', ?, '%')
寫法 - 不要用變量直接拼接到 SQL 字符串里
三、查詢單條記錄
如果只查一行,可以直接用 fetch_assoc()
拿一次。
php復制編輯$stmt = $mysqli->prepare("SELECT id, username, email FROM users WHERE id = ?");
$stmt->bind_param('i', $user_id);
$stmt->execute();$result = $stmt->get_result();
$user = $result->fetch_assoc();
$stmt->close();// 檢查是否查到
if (!$user) {throw new Exception('用戶不存在');
}return $user;
fetch_assoc()
只取一行,后面不用循環- 查不到數據時要有異常/提示處理
四、分頁查詢(帶總數)
分頁查詢是非常常見需求,要返回數據和總數。
$page = 1;
$page_size = 10;
$offset = ($page - 1) * $page_size;// 1. 查詢數據
$stmt = $mysqli->prepare("SELECT id, username, email FROM users WHERE status = 1 LIMIT ?, ?");
$stmt->bind_param('ii', $offset, $page_size);
$stmt->execute();
$result = $stmt->get_result();
$list = [];
while ($row = $result->fetch_assoc()) {$list[] = $row;
}
$stmt->close();// 2. 查詢總條數
$sql_total = "SELECT COUNT(*) AS total FROM users WHERE status = 1";
$res_total = $mysqli->query($sql_total);
$total_row = $res_total->fetch_assoc();
$total = (int)$total_row['total'];
$res_total->free();// 返回分頁結果
return ['list' => $list,'total' => $total
];
- 分頁必須返回數據列表 + 總條數
- 分開兩次查詢更穩(一次查數據,一次查總數)
五、復雜條件動態查詢(實戰重點)
有些條件是用戶輸入的,要動態拼條件,但還要防注入。常規做法是動態構造 SQL + 參數綁定。
$conditions = [];
$params = [];
$types = '';// 假設有用戶搜索過濾
if (!empty($filter['username'])) {$conditions[] = "username LIKE CONCAT('%', ?, '%')";$params[] = $filter['username'];$types .= 's';
}
if (isset($filter['status'])) {$conditions[] = "status = ?";$params[] = (int)$filter['status'];$types .= 'i';
}$where = $conditions ? 'WHERE ' . implode(' AND ', $conditions) : '';$sql = "SELECT id, username, email FROM users $where ORDER BY created_at DESC LIMIT 20";
$stmt = $mysqli->prepare($sql);
if ($params) {$stmt->bind_param($types, ...$params);
}
$stmt->execute();
$result = $stmt->get_result();$data = [];
while ($row = $result->fetch_assoc()) {$data[] = $row;
}
$stmt->close();return $data;
- 拼接 SQL 時 條件動態組裝,值用綁定
- 類型字符串
$types
也要跟著參數增長 - 防止 SQL 注入,同時又靈活
總結
方面 | 要點 |
---|---|
查詢數據 | query 或 prepare + get_result |
查詢多行 | while(fetch_assoc) |
查詢單行 | fetch_assoc 直接用 |
分頁查詢 | 兩次查詢:數據和總數分開 |
防SQL注入 | 預處理 + bind_param |
動態條件 | 組裝 WHERE 和 參數,分離綁定 |
穩定性保障 | 任何 query 或 prepare 后必須判斷成功 |
字符集設置 | $mysqli->set_charset('utf8mb4') 避免亂碼 |
四,相關函數
一,核心函數分類及用法
1. 連接與關閉
-
創建連接:
// 面向對象 $mysqli = new mysqli("localhost", "user", "password", "database", 3306);// 過程式 $link = mysqli_connect("localhost", "user", "password", "database", 3306);
- 失敗行為:默認返回
false
,但若啟用MYSQLI_REPORT_STRICT
模式,會拋出mysqli_sql_exception
。
- 失敗行為:默認返回
-
檢查連接錯誤:
// 面向對象 if ($mysqli->connect_errno) {die("連接失敗: " . $mysqli->connect_error); }// 過程式 if (mysqli_connect_errno()) {die("連接失敗: " . mysqli_connect_error()); }
-
關閉連接:
$mysqli->close(); // 面向對象 mysqli_close($link); // 過程式
2. 執行查詢
-
執行普通查詢:
// 面向對象 $result = $mysqli->query("SELECT * FROM users"); // 過程式 $result = mysqli_query($link, "SELECT * FROM users");
- 返回值:
- 成功(SELECT/SHOW/DESCRIBE)返回
mysqli_result
對象。 - 成功(INSERT/UPDATE/DELETE)返回
true
。 - 失敗返回
false
(或拋出異常)。
- 成功(SELECT/SHOW/DESCRIBE)返回
- 返回值:
-
獲取結果數據:
// 獲取關聯數組 while ($row = $result->fetch_assoc()) {echo $row["name"]; }// 或直接獲取所有數據 $data = $result->fetch_all(MYSQLI_ASSOC);
3. 預處理語句(防 SQL 注入)
-
步驟:
prepare()
→bind_param()
→execute()
→get_result()
。$stmt = $mysqli->prepare("INSERT INTO users (name, email) VALUES (?, ?)"); $name = "Alice"; $email = "alice@example.com";// 綁定參數(類型標識符:s=string, i=int, d=double, b=blob) $stmt->bind_param("ss", $name, $email);// 執行 $stmt->execute();// 獲取插入的 ID $inserted_id = $stmt->insert_id;// 關閉預處理語句 $stmt->close();
4. 事務處理
-
開啟事務:
$mysqli->begin_transaction();try {$mysqli->query("UPDATE account SET balance = balance - 100 WHERE user_id = 1");$mysqli->query("UPDATE account SET balance = balance + 100 WHERE user_id = 2");$mysqli->commit(); // 提交事務 } catch (mysqli_sql_exception $e) {$mysqli->rollback(); // 回滾echo "事務失敗: " . $e->getMessage(); }
5. 錯誤與異常處理
-
啟用嚴格異常模式:
$driver = new mysqli_driver(); $driver->report_mode = MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ERROR;
-
捕獲異常:
try {$mysqli->query("INVALID SQL"); } catch (mysqli_sql_exception $e) {echo "錯誤信息: " . $e->getMessage();echo "錯誤代碼: " . $e->getCode(); }
二、PHP 8.0 關鍵變更與適配
1. 類型嚴格性
-
參數類型檢查:
例如mysqli_query($link, 123)
中的第二個參數必須為字符串,否則拋出TypeError
。// PHP 8.0 會報錯,PHP 7.x 僅警告 $mysqli->query(123); // 錯誤:參數必須為字符串
2. 棄用與移除
- 棄用函數:
mysqli::get_client_info()
(無參數調用)需改為mysqli_get_client_info()
。
- 移除別名:
mysqli_bind_param()
和mysqli_bind_result()
已移除,僅保留mysqli_stmt_bind_param()
。
三、常用函數速查表
函數 | 用途 | 示例 |
---|---|---|
mysqli_connect() | 建立數據庫連接 | $link = mysqli_connect(...) |
mysqli_query() | 執行 SQL 查詢 | $result = mysqli_query($link, $sql) |
mysqli_prepare() | 創建預處理語句 | $stmt = mysqli_prepare($link, $sql) |
mysqli_stmt_bind_param() | 綁定預處理語句參數 | mysqli_stmt_bind_param($stmt, "si", ...) |
mysqli_fetch_assoc() | 獲取關聯數組結果 | $row = mysqli_fetch_assoc($result) |
mysqli_insert_id() | 獲取最后插入的 ID | $id = mysqli_insert_id($link) |
mysqli_affected_rows() | 獲取受影響的行數 | $count = mysqli_affected_rows($link) |
mysqli_real_escape_string() | 轉義字符串(用于非預處理語句) | $safe = mysqli_real_escape_string($link, $input) |
四、最佳實踐
-
始終使用預處理語句:避免 SQL 注入,尤其是處理用戶輸入時。
-
啟用異常模式:
$driver = new mysqli_driver(); $driver->report_mode = MYSQLI_REPORT_STRICT | MYSQLI_REPORT_ERROR;
-
關閉調試信息:生產環境中隱藏數據庫錯誤細節,記錄到日志文件。
-
資源釋放:及時關閉
mysqli_result
和預處理語句對象。
項目名稱:學生信息管理系統
功能需求
- 查看學生列表
- 添加新學生
- 編輯學生信息
- 刪除學生
- 簡單的搜索功能
技術棧
- 前端:HTML + Bootstrap 5(極簡界面)
- 后端:PHP 8.0+(面向過程編程)
- 數據庫:MySQL 5.7+
- 安全:MySQLi 預處理語句、輸入過濾
項目結構
/student_manager
├── index.php # 顯示學生列表
├── create.php # 添加新學生
├── edit.php # 編輯學生信息
├── delete.php # 刪除學生
├── config.php # 數據庫配置
└── style.css # 簡單樣式
數據庫設計
表名:students
CREATE TABLE students (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL,email VARCHAR(100) UNIQUE NOT NULL,age INT NOT NULL
);
核心代碼實現
1. 數據庫配置文件 (config.php
)
<?php
// 數據庫配置
$host = 'localhost';
$user = 'root';
$password = '123456';
$database = 'student_db';// 創建連接
$mysqli = new mysqli($host, $user, $password, $database);// 檢查連接
if ($mysqli->connect_error) {die("連接失敗: " . $mysqli->connect_error);
}// 設置字符集
$mysqli->set_charset('utf8mb4');
?>
2. 顯示學生列表 (index.php
)
<?php
include 'config.php';// 搜索功能
$search = $_GET['search'] ?? '';
$query = "SELECT * FROM students";
if (!empty($search)) {$query .= " WHERE name LIKE ?";$stmt = $mysqli->prepare($query);$search_term = "%$search%";$stmt->bind_param('s', $search_term);
} else {$stmt = $mysqli->prepare($query);
}$stmt->execute();
$result = $stmt->get_result();
?><!DOCTYPE html>
<html>
<head><title>學生管理系統</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5"><h2>學生列表</h2><!-- 搜索框 --><form class="mb-3"><input type="text" name="search" placeholder="輸入姓名搜索" class="form-control"><button type="submit" class="btn btn-primary mt-2">搜索</button></form><!-- 添加學生鏈接 --><a href="create.php" class="btn btn-success mb-3">添加新學生</a><!-- 學生表格 --><table class="table table-striped"><thead><tr><th>ID</th><th>姓名</th><th>郵箱</th><th>年齡</th><th>操作</th></tr></thead><tbody><?php while ($row = $result->fetch_assoc()): ?><tr><td><?= htmlspecialchars($row['id']) ?></td><td><?= htmlspecialchars($row['name']) ?></td><td><?= htmlspecialchars($row['email']) ?></td><td><?= htmlspecialchars($row['age']) ?></td><td><a href="edit.php?id=<?= $row['id'] ?>" class="btn btn-warning btn-sm">編輯</a><a href="delete.php?id=<?= $row['id'] ?>" class="btn btn-danger btn-sm" onclick="return confirm('確認刪除?')">刪除</a></td></tr><?php endwhile; ?></tbody></table>
</div>
</body>
</html>
3. 添加學生 (create.php
)
<?php
include 'config.php';if ($_SERVER['REQUEST_METHOD'] === 'POST') {$name = $_POST['name'];$email = $_POST['email'];$age = $_POST['age'];// 使用預處理語句防止SQL注入$stmt = $mysqli->prepare("INSERT INTO students (name, email, age) VALUES (?, ?, ?)");$stmt->bind_param('ssi', $name, $email, $age);if ($stmt->execute()) {header('Location: index.php'); // 添加成功跳轉exit;} else {$error = "添加失敗: " . $stmt->error;}
}
?><!DOCTYPE html>
<html>
<head><title>添加學生</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5"><h2>添加新學生</h2><?php if (!empty($error)): ?><div class="alert alert-danger"><?= $error ?></div><?php endif; ?><form method="POST"><div class="mb-3"><label class="form-label">姓名</label><input type="text" name="name" class="form-control" required></div><div class="mb-3"><label class="form-label">郵箱</label><input type="email" name="email" class="form-control" required></div><div class="mb-3"><label class="form-label">年齡</label><input type="number" name="age" class="form-control" required></div><button type="submit" class="btn btn-primary">提交</button></form>
</div>
</body>
</html>
4. 編輯學生 (edit.php
)
<?php
include 'config.php';// 獲取當前學生信息
$id = $_GET['id'];
$stmt = $mysqli->prepare("SELECT * FROM students WHERE id = ?");
$stmt->bind_param('i', $id);
$stmt->execute();
$student = $stmt->get_result()->fetch_assoc();if ($_SERVER['REQUEST_METHOD'] === 'POST') {$name = $_POST['name'];$email = $_POST['email'];$age = $_POST['age'];$stmt = $mysqli->prepare("UPDATE students SET name=?, email=?, age=? WHERE id=?");$stmt->bind_param('ssii', $name, $email, $age, $id);if ($stmt->execute()) {header('Location: index.php'); // 更新成功跳轉exit;} else {$error = "更新失敗: " . $stmt->error;}
}
?><!DOCTYPE html>
<html>
<head><title>編輯學生</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5"><h2>編輯學生信息</h2><?php if (!empty($error)): ?><div class="alert alert-danger"><?= $error ?></div><?php endif; ?><form method="POST"><div class="mb-3"><label class="form-label">姓名</label><input type="text" name="name" class="form-control" value="<?= htmlspecialchars($student['name']) ?>" required></div><div class="mb-3"><label class="form-label">郵箱</label><input type="email" name="email" class="form-control" value="<?= htmlspecialchars($student['email']) ?>" required></div><div class="mb-3"><label class="form-label">年齡</label><input type="number" name="age" class="form-control" value="<?= htmlspecialchars($student['age']) ?>" required></div><button type="submit" class="btn btn-primary">更新</button></form>
</div>
</body>
</html>
5. 刪除學生 (delete.php
)
<?php
include 'config.php';if (isset($_GET['id'])) {$id = $_GET['id'];$stmt = $mysqli->prepare("DELETE FROM students WHERE id = ?");$stmt->bind_param('i', $id);if ($stmt->execute()) {header('Location: index.php'); // 刪除成功跳轉} else {die("刪除失敗: " . $stmt->error);}
}
?>
安全措施
- SQL注入防護
- 所有用戶輸入通過
prepare
+bind_param
處理。
- 所有用戶輸入通過
- XSS防護
- 使用
htmlspecialchars()
轉義所有動態輸出。
- 使用
- 數據驗證
- 前端使用
required
屬性確保必填字段。 - 后端檢查
$_SERVER['REQUEST_METHOD']
防止直接訪問。
- 前端使用