
本文介绍如何从数据库动态加载旅游景点、住宿等服务选项,通过复选框供客户选择,并针对“按人计费”(如门票、酒店)和“按团/次计费”(如啤酒箱、包车接送)两类价格模式,实现精准、可扩展的总价自动计算。
本文介绍如何从数据库动态加载旅游景点、住宿等服务选项,通过复选框供客户选择,并针对“按人计费”(如门票、酒店)和“按团/次计费”(如啤酒箱、包车接送)两类价格模式,实现精准、可扩展的总价自动计算。
在定制化船游服务中,行程地点、附加服务(如住宿、餐饮、交通)常随季节或运营策略调整,因此需将这些选项与对应价格存入数据库,并在前端动态渲染为可勾选的复选框列表。关键挑战在于:部分费用按游客人数($ppl)累加(如每人150元码头入场费),而另一些则为固定团费(如整箱啤酒380元、全程包车650元),与人数无关。若统一乘以 $ppl,将导致严重计费错误。
✅ 推荐实现方案:分离计费逻辑 + 显式配置标识
避免在循环中硬编码条件判断(如 if ($place === 'Case of beer')),应将计费规则外置为结构化配置,提升可维护性与可扩展性:
<?php
// 1. 从数据库获取所有可选服务(示例数据)
$services = [
['id' => 1, 'name' => 'Sibaltan Pier Entrance', 'price' => 150.00, 'per_person' => true],
['id' => 2, 'name' => 'Case of beer', 'price' => 380.00, 'per_person' => false],
['id' => 3, 'name' => 'Van Transfer Sibaltan', 'price' => 650.00, 'per_person' => false],
['id' => 4, 'name' => 'Overnight at Coral Lodge', 'price' => 2200.00, 'per_person' => true],
];
// 2. 假设已获取用户已选服务ID数组(来自POST或会话)
$selected_ids = [1, 2, 4]; // 用户勾选了码头、啤酒、住宿
$ppl = 6; // 当前团队人数
// 3. 计算总价:遍历所选服务,按 per_person 标志决定是否乘以人数
$total_price = 0.00;
foreach ($services as $svc) {
if (in_array($svc['id'], $selected_ids)) {
$unit_price = $svc['price'];
$multiplier = $svc['per_person'] ? $ppl : 1;
$total_price += $unit_price * $multiplier;
}
}
// 4. 渲染复选框列表(含当前选中状态)
echo '<form method="post">';
foreach ($services as $svc) {
$checked = in_array($svc['id'], $selected_ids) ? ' checked' : '';
echo "<label><input type='checkbox' name='spots[]' value='{$svc['id']}'{$checked}> ";
echo "{$svc['name']} - ₱" . number_format($svc['price'], 2);
echo $svc['per_person'] ? " (per person)" : " (flat fee)";
echo "</label><br>";
}
echo '<input type="submit" value="Recalculate Total">';
echo '</form>';
echo "<p><strong>Total Cost: ₱" . number_format($total_price, 2) . "</strong></p>";
?>⚠️ 关键注意事项
-
数据库设计建议:在服务表中增加布尔字段
is_per_person(或billing_mode ENUM('per_person','per_group')),避免代码中硬编码服务名称; -
安全防护:实际生产中,
$selected_ids必须经filter_var()或白名单校验,防止注入恶意ID; -
精度处理:货币运算推荐使用整数分(如存储38000代替380.00)或
bcmath扩展,规避浮点误差; - 用户体验优化:可为“按团计费”项添加视觉提示(如图标?或灰色标签),帮助客户理解费用逻辑。
此方案将业务规则(计费模式)与展示逻辑解耦,既保障了计算准确性,又为未来新增服务(如“潜水教练配比”、“保险套餐”)提供了零代码修改的扩展能力——只需在数据库中新增一行记录并设置 per_person 值即可。



















