
本文介绍在 PHP 中高效判断当前日期是否未出现在分组工作日数组中,并据此构建非工作日列表的完整实现方法,涵盖 array_column 与 in_array 的正确组合用法、避免重复逻辑、日期格式对齐及结构化输出。
本文介绍在 php 中高效判断当前日期是否未出现在分组工作日数组中,并据此构建非工作日列表的完整实现方法,涵盖 `array_column` 与 `in_array` 的正确组合用法、避免重复逻辑、日期格式对齐及结构化输出。
在实际考勤或排班系统中,常需基于预设的「工作日规则」(如每组指定周几为工作日)动态识别当日是否为某组的「非工作日」。原始需求是:给定一个含 group_id 和 day(1=周日,2=周一…7=周六)的对象数组 $work_day_arr,需找出所有未将当天设为工作日的分组,并生成形如 ['attendance_group_id' => 'xxx', 'off_date' => 'Y-m-d'] 的 $day_off 列表。
但原代码存在三个关键问题:
- 逻辑错误:if($work_day->day != $day_now + 1) 中 $work_day 未定义(应为 $work_hour),且 date('N') 返回 1–7(周一至周日),而数据中 day=1 表示周日,二者语义不一致;
- 重复写入:对每个不匹配的 $work_hour 都追加一条记录,导致同一 group_id 多次出现(如示例中 group_id 出现 5 次);
- 检测粒度错误:应在「每个 group_id 维度」判断其是否完全未包含当天,而非逐条比对。
✅ 正确解法是:按 group_id 分组 → 提取各组的工作日数字集合 → 检查当前星期几是否不在该集合中。核心工具是 array_column($array, 'column', 'key') 配合 in_array():
// 1. 获取今日星期几(PHP date('N'):1=周一, 7=周日)
$todayWeekday = (int) date('N'); // 注意:数据中 day=1 表示周日 → 需统一映射!
// 2. 修正日期映射:将 date('N') 转为「1=周日」标准(即:周日→1,周一→2...周六→7)
$normalizedToday = $todayWeekday === 1 ? 7 : $todayWeekday - 1; // 1→7, 2→1, 3→2...7→6
// 3. 按 group_id 分组工作日数据
$groupedWorkDays = [];
foreach ($work_day_arr as $item) {
$groupId = $item->group_id;
if (!isset($groupedWorkDays[$groupId])) {
$groupedWorkDays[$groupId] = [];
}
$groupedWorkDays[$groupId][] = (int) $item->day;
}
// 4. 遍历每个分组,检查 normalizedToday 是否不在其工作日列表中
$day_off = [];
$date_now = date('Y-m-d'); // 确保日期格式统一
foreach ($groupedWorkDays as $groupId => $workDays) {
// 使用 in_array 检查当前标准化星期几是否缺失
if (!in_array($normalizedToday, $workDays, true)) {
$day_off[] = (object) [
'attendance_group_id' => $groupId,
'off_date' => $date_now
];
}
}? 关键注意事项:
- 日期映射必须统一:date('N') 周一为 1,但业务数据中周日为 1,因此需做转换($normalizedToday = $todayWeekday === 1 ? 7 : $todayWeekday - 1);
- 避免重复:使用 array_column($work_day_arr, 'day', 'group_id') 无法直接满足分组需求(会覆盖同 group_id 多条记录),必须手动分组;
- 严格类型比较:in_array($val, $arr, true) 启用严格模式,防止 1 == '1' 类型隐式转换导致误判;
- 性能提示:若数据量大,可预先对 $workDays 数组 array_unique() 去重,再 array_values() 重置索引。
最终 $day_off 将为每个「未安排今日工作」的分组生成唯一一条记录,结构清晰,无冗余,符合生产环境健壮性要求。

















