
本文介绍如何通过 mysql 关系型设计与 php 安全编码,将汽车详情(如品牌、型号)与用户预订信息(如租期、姓名)统一存入数据库,并确保数据可查、可管、可扩展。
本文介绍如何通过 mysql 关系型设计与 php 安全编码,将汽车详情(如品牌、型号)与用户预订信息(如租期、姓名)统一存入数据库,并确保数据可查、可管、可扩展。
要实现汽车租赁网站中“车辆信息”与“用户预订”数据的可靠整合,关键不在于简单拼接字段,而在于构建符合关系型数据库范式的结构化模型,并配合安全、可维护的 PHP 逻辑。
一、数据库关系设计(核心基础)
首先,在 MySQL 中创建两个规范表,通过外键建立强关联:
-- 汽车信息表(主表)
CREATE TABLE cars (
id INT PRIMARY KEY AUTO_INCREMENT,
brand VARCHAR(50) NOT NULL,
model VARCHAR(50) NOT NULL,
year YEAR,
price_per_day DECIMAL(8,2),
status ENUM('available', 'booked', 'maintenance') DEFAULT 'available'
);
-- 预订信息表(从表,关联 car_id)
CREATE TABLE bookings (
id INT PRIMARY KEY AUTO_INCREMENT,
car_id INT NOT NULL,
customer_name VARCHAR(100) NOT NULL,
phone VARCHAR(20),
start_date DATE NOT NULL,
end_date DATE NOT NULL,
total_amount DECIMAL(10,2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (car_id) REFERENCES cars(id) ON DELETE CASCADE
);
✅ 关键点:bookings.car_id 是外键,指向 cars.id。这确保每条预订必然对应一辆真实存在的汽车,且在 phpMyAdmin 中可通过“浏览”或执行 SELECT * FROM bookings JOIN cars ON bookings.car_id = cars.id 直观查看完整关联记录。
二、PHP 安全写入流程(避免常见漏洞)
提交表单时,需分别处理车辆选择(如隐藏域传 car_id)与用户输入,并使用 PDO 预处理语句防止 SQL 注入:
<?php // 数据库连接(推荐使用 PDO)
$pdo = new PDO("mysql:host=localhost;dbname=car_rental;charset=utf8mb4", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
// 1. 获取并验证输入(示例:预订表单)
$car_id = (int)$_POST['car_id']; // 强制转整型,防注入
$customer_name = htmlspecialchars(trim($_POST['customer_name']));
$start_date = date('Y-m-d', strtotime($_POST['start_date']));
$end_date = date('Y-m-d', strtotime($_POST['end_date']));
// 2. 预处理插入预订记录
$stmt = $pdo->prepare("
INSERT INTO bookings (car_id, customer_name, start_date, end_date, total_amount)
VALUES (?, ?, ?, ?, ?)
");
$total_amount = calculateTotal($car_id, $start_date, $end_date); // 自定义计算逻辑
$stmt->execute([$car_id, $customer_name, $start_date, $end_date, $total_amount]);
echo "✅ 预订成功!ID:" . $pdo->lastInsertId();
} catch (PDOException $e) {
error_log("Booking insert failed: " . $e->getMessage());
echo "❌ 提交失败,请稍后重试。";
}
}
// 示例:根据 car_id 和日期计算费用(需补充实际逻辑)
function calculateTotal($car_id, $start, $end) {
global $pdo;
$stmt = $pdo->prepare("SELECT price_per_day FROM cars WHERE id = ?");
$stmt->execute([$car_id]);
$price = $stmt->fetchColumn() ?: 0;
$days = (strtotime($end) - strtotime($start)) / 86400 + 1;
return round($price * $days, 2);
}
?>
⚠️ 重要安全实践:
- 永远不用 $_POST 直接拼接 SQL;
- 对数字型 ID 使用 (int) 强制转换;
- 对字符串使用 htmlspecialchars() 输出前转义(防止 XSS);
- 所有数据库操作必须用 prepare() + execute() 实现参数化查询。
三、在 phpMyAdmin 中验证与查询
提交成功后,您可在 phpMyAdmin 中:
- 点击 bookings 表 → “浏览”,查看新纪录;
- 执行联合查询快速核对关联数据:
SELECT b.id AS booking_id, c.brand, c.model, b.customer_name, b.start_date, b.end_date, b.total_amount FROM bookings b JOIN cars c ON b.car_id = c.id ORDER BY b.created_at DESC LIMIT 20;
这样既保证了数据完整性,又便于后续扩展(如添加支付状态、司机信息等字段),同时为报表统计、后台管理打下坚实基础。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











