
本文详解如何为多个房间分别计算一组选定日期的总价格——对每个日期,优先使用 `options` 中匹配的特定价格,未匹配则 fallback 到 `default_price`,并汇总得出各房间的 `total_price`。
在酒店预订、会议室租赁等场景中,常需根据用户选择的连续日期(如入住/退房区间),动态计算不同房型的总费用。关键逻辑在于:每个日期单独判断价格来源——若该日期在房间的 options 数组中存在明确配置,则采用对应 price;否则统一使用 default_price。最终将所有选中日期的价格相加,即为该房间的 total_price。
以下是一个简洁、可读性强且无副作用的实现方案(兼容 PHP 7.4+):
$selectedDates = ['10-04-2022', '11-04-2022', '12-04-2022'];
$setRooms = [
[
'id' => 1,
'title' => 'Room1',
'default_price' => 50,
'options' => [
['date' => '12-04-2022', 'price' => 100],
['date' => '13-04-2022', 'price' => 200],
['date' => '14-04-2022', 'price' => 200],
]
],
[
'id' => 2,
'title' => 'Room2',
'default_price' => 120,
'options' => [
['date' => '11-04-2022', 'price' => 200],
['date' => '12-04-2022', 'price' => 300],
['date' => '13-04-2022', 'price' => 400],
]
],
];
$result = [];
foreach ($setRooms as $room) {
$total = 0;
foreach ($selectedDates as $date) {
// 精确匹配 date 字段(字符串相等,避免 Carbon 解析开销)
$matchedOptions = array_filter($room['options'], fn($opt) => $opt['date'] === $date);
if (count($matchedOptions) === 1) {
$total += current($matchedOptions)['price'];
} else {
$total += $room['default_price'];
}
}
$result[] = [
'id' => $room['id'],
'title' => $room['title'],
'total_price' => $total
];
}
print_r($result);✅ 输出结果:
Array
(
[0] => Array
(
[id] => 1
[title] => Room1
[total_price] => 200 // 50 + 50 + 100
)
[1] => Array
(
[id] => 2
[title] => Room2
[total_price] => 620 // 120 + 200 + 300
)
)⚠️ 关键注意事项:
- 勿复用累加变量:原始代码中 $price 在外层循环外定义,导致房间间价格相互污染。务必为每个房间重置 $total = 0。
- 避免日期格式转换开销:示例中直接使用字符串比对(===),前提是输入日期格式严格统一(如 'd-m-Y')。若需兼容多种格式(如 'Y-m-d'),再引入 Carbon::parse() 并标准化格式。
- array_filter + current() 更安全:相比手动遍历或 array_key_first(),current() 可安全获取首个匹配项(即使键非数字),且语义清晰。
- 性能提示:若 options 数量极大(>1000 条),建议预先构建 date → price 的哈希映射(如 array_column($room['options'], 'price', 'date')),将单次查找从 O(n) 优化至 O(1)。
该方案结构清晰、无外部依赖、易于单元测试,适用于 Laravel、Symfony 或纯 PHP 项目。










