PHP中如何遍历数组根据给定日期规则设置对应车辆价格
解决思路
你出现属性不存在报错的核心原因是大小写不匹配:数据结构中时间字段名是全小写的startdate/enddate,但原代码里判断的是驼峰格式的startDate,字段名对应不上就会触发属性不存在的错误。
匹配逻辑说明
我们按「规则越具体优先级越高」的原则设计匹配顺序,覆盖所有规则场景:
- 最高优先级:同时有
startdate和enddate的规则,判断当前时间是否落在区间内 - 次高优先级:仅存在
startdate的规则,判断当前时间大于等于起始时间 - 次高优先级:仅存在
enddate的规则,判断当前时间小于等于结束时间 - 最低优先级:无任何时间字段的默认规则,作为兜底使用
如果需要匹配特定车型/车辆类型,可在循环中增加对应字段的过滤条件,比如需要本田豪华型就加$price->type == 'Luxury' && $car->name == 'Honda'的判断
可运行代码示例
$today = strtotime(Carbon::now()->toDateString()) * 1000; foreach ($cars as $car) { // 初始化当前车辆的匹配价格 $conditionPrice = null; foreach ($car->prices as $price) { $isMatch = false; $hasStart = property_exists($price, 'startdate'); $hasEnd = property_exists($price, 'enddate'); // 场景1:同时有起止时间,判断是否在区间内 if ($hasStart && $hasEnd) { if ($today >= $price->startdate && $today <= $price->enddate) { $isMatch = true; } // 场景2:只有开始时间,判断大于等于开始时间 } elseif ($hasStart) { if ($today >= $price->startdate) { $isMatch = true; } // 场景3:只有结束时间,判断小于等于结束时间 } elseif ($hasEnd) { if ($today <= $price->enddate) { $isMatch = true; } // 场景4:无时间字段的兜底规则,最后再判断 } else { continue; } // 匹配到更高优先级的规则就更新价格 if ($isMatch) { $conditionPrice = $price->price; // 最高优先级的区间规则匹配到后可直接跳出循环节省性能 if ($hasStart && $hasEnd) break; } } // 所有具体规则都没匹配到的话,取无时间字段的兜底价格 if (is_null($conditionPrice)) { foreach ($car->prices as $price) { if (!property_exists($price, 'startdate') && !property_exists($price, 'enddate')) { $conditionPrice = $price->price; break; } } } // 最终匹配到的价格可直接赋值给车辆对象 $car->current_price = $conditionPrice; }
规则验证
上述代码完全匹配你给出的本田豪华型定价要求:
- 当日为8月10日:无其他匹配,兜底取6000
- 当日为8月28日:匹配仅带startdate的8月27日规则,取4000
- 当日为9月10日:匹配带起止的9月规则,取8000
- 当日为10月5日:匹配仅带startdate的8月27日规则,取4000
内容的提问来源于stack exchange,提问作者Siona Fernandes
相关产品推荐
相关产品推荐

