本文延續第一篇(資料庫建立與基礎操作),構建完整的「首頁列表 → 新增表單 → 處理入庫 → 重導向列表」閉環,詳細講解 PHP 與 MySQL 互動的核心模式:連接、查詢、結果集遍歷、表單提交、預處理寫入。
index.php:首頁,顯示資料表所有記錄add.php:新增記錄表單頁add_process.php:表單處理,寫入資料庫links.inc:共用導航選單(include 復用)config.php:資料庫連接配置(生產環境必須外置)<?php
// config.php
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', 'password');
define('DB_NAME', 'example');
define('DB_CHARSET', 'utf8mb4');
function getDbConnection() {
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($conn->connect_error) {
error_log("DB Connect Failed: " . $conn->connect_error);
die("系統暫時不可用,請稍後再試");
}
$conn->set_charset(DB_CHARSET);
return $conn;
}
<?php
// index.php
require_once 'config.php';
$conn = getDbConnection();
$sql = "SELECT idx, UserName, LastName, FreeText FROM tbl ORDER BY idx DESC";
$result = $conn->query($sql);
?>
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>資料列表</title></head>
<body>
<h1>資料列表</h1>
<?php include 'links.inc'; ?>
<table border="1" cellpadding="5">
<tr><th>ID</th><th>姓名</th><th>姓氏</th><th>備註</th></tr>
<?php if ($result->num_rows > 0): ?>
<?php while ($row = $result->fetch_assoc()): ?>
<tr>
<td><?= $row['idx'] ?></td>
<td><?= htmlspecialchars($row['UserName']) ?></td>
<td><?= htmlspecialchars($row['LastName']) ?></td>
<td><?= htmlspecialchars($row['FreeText']) ?></td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr><td colspan="4">暫無資料</td></tr>
<?php endif; ?>
</table>
<?php $conn->close(); ?>
</body>
</html>
核心講解:
mysqli_connect() / new mysqli():建立連接,失敗即終止$conn->query():執行 SELECT,回傳 mysqli_result 物件fetch_assoc():逐行取得關聯陣列,鍵為欄位名htmlspecialchars():輸出編碼防 XSS,所有動態內容輸出 HTML 必須呼叫include:複用導航、頁尾、配置等共用片段<?php // add.php ?>
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>新增記錄</title></head>
<body>
<h1>新增記錄</h1>
<?php include 'links.inc'; ?>
<form method="post" action="add_process.php">
<div>ID: <input type="number" name="idx" min="1" required></div>
<div>姓名: <input type="text" name="UserName" maxlength="30" required></div>
<div>姓氏: <input type="text" name="LastName" maxlength="50" required></div>
<div>備註: <input type="text" name="FreeText" maxlength="100"></div>
<button type="submit">送出</button>
</form>
</body>
</html>
表單設計要點:
• method="post":寫入操作必須用 POST
• action="add_process.php":分離顯示與處理邏輯
• name 對應資料庫欄位名(慣例),處理頁直接對應
• required、maxlength:瀏覽器端首輪驗證
<?php
// add_process.php
require_once 'config.php';
$conn = getDbConnection();
$idx = $_POST['idx'] ?? '';
$UserName = $_POST['UserName'] ?? '';
$LastName = $_POST['LastName'] ?? '';
$FreeText = $_POST['FreeText'] ?? '';
// 基礎驗證
if (!$idx || !$UserName || !$LastName) {
die("必填欄位不可為空");
}
$stmt = $conn->prepare("INSERT INTO tbl (idx, UserName, LastName, FreeText) VALUES (?, ?, ?, ?)");
$stmt->bind_param("isss", $idx, $UserName, $LastName, $FreeText);
if ($stmt->execute()) {
header("Location: index.php"); // PRG 模式
exit;
} else {
error_log("Insert failed: " . $stmt->error);
die("新增失敗,請稍後再試");
}
關鍵安全實踐:
prepare() + bind_param() 徹底防 SQL 注入header("Location: ...") 重導向,防止使用者重整頁面重複提交error_log() 記錄詳細錯誤,使用者端顯示友善訊息<!-- links.inc -->
<nav>
<a href="index.php">首頁</a> |
<a href="add.php">新增記錄</a> |
<a href="edit_list.php">編輯記錄</a> |
<a href="delete_list.php">刪除記錄</a>
</nav>
<hr>
query(),寫入用 prepare())fetch_assoc() 遍歷 / execute() 寫入)這套模式是所有 PHP MySQL 應用的基石,熟練掌握後即可引入 PDO、Laravel Eloquent、Doctrine 等現代工具提升開發效率與安全性。