You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP日程重叠限制问题:现有代码无法检测全时段覆盖冲突

日程冲突检测代码漏洞修复

现有一段PHP日程添加代码,仅能检测部分时段重叠的日程冲突,但存在漏洞:当新增日程完全覆盖已有日程时(例如已存在7:00-8:30的日程,新增6:30-9:00的日程),代码无法识别冲突并会成功添加;而其他部分重叠场景(如6:30-7:30、7:30-9:30)能正常触发冲突报错。

原代码示例:

$d_start = strtotime($datetime_start);
$d_end = strtotime($datetime_end);
$roomID = $assembly_hall_id;

$chk = $this->conn->query("SELECT * FROM `schedule_list` where (('{$d_start}'   
Between unix_timestamp(datetime_start) and unix_timestamp(datetime_end)) or ('{$d_end}' 
Between unix_timestamp(datetime_start) and unix_timestamp(datetime_end))) ".(($roomID > 0) ? "
and assembly_hall_id ='{$roomID}' and sched_status = '1' " : ""))->num_rows;

if($chk > 0 ){
    $resp['status'] = 'failed';
    $resp['err_msg'] = "The schedule is conflict with other schedules.";
}elseif(strtotime($datetime_start) == null)
{   
    $resp['status'] = 'failed';
    $resp['err_msg'] = "Date and Time Schedule is Invalid.";
}

问题根源

原SQL查询只判断了新增日程的开始/结束时间是否落在已有日程的时段内,但完全覆盖已有日程的场景下,新增日程的开始时间早于已有日程的开始时间、结束时间晚于已有日程的结束时间,此时$d_start和$d_end都不在已有日程的时间区间内,导致查询不到冲突记录。

修复方案

需要覆盖所有时间区间重叠的场景:判断两个时间区间是否存在交集,即新增日程的开始时间 < 已有日程的结束时间,且新增日程的结束时间 > 已有日程的开始时间。

修复后的代码:

$d_start = strtotime($datetime_start);
$d_end = strtotime($datetime_end);
$roomID = $assembly_hall_id;

// 重构冲突判断逻辑,覆盖所有重叠场景
$where = "WHERE unix_timestamp(datetime_start) < {$d_end} AND unix_timestamp(datetime_end) > {$d_start}";
if($roomID > 0){
    $where .= " AND assembly_hall_id = '{$roomID}' AND sched_status = '1'";
}

$chk = $this->conn->query("SELECT * FROM `schedule_list` {$where}")->num_rows;

if($chk > 0 ){
    $resp['status'] = 'failed';
    $resp['err_msg'] = "该日程与已有日程冲突。";
}elseif($d_start === false || $d_end === false) // 同时校验开始/结束时间有效性
{   
    $resp['status'] = 'failed';
    $resp['err_msg'] = "日程日期或时间格式无效。";
}

额外优化建议

  • 防范SQL注入:建议使用预处理语句替代直接变量拼接,示例:
if($roomID > 0){
    $stmt = $this->conn->prepare("SELECT * FROM `schedule_list` WHERE unix_timestamp(datetime_start) < ? AND unix_timestamp(datetime_end) > ? AND assembly_hall_id = ? AND sched_status = '1'");
    $stmt->bind_param("iii", $d_end, $d_start, $roomID);
}else{
    $stmt = $this->conn->prepare("SELECT * FROM `schedule_list` WHERE unix_timestamp(datetime_start) < ? AND unix_timestamp(datetime_end) > ?");
    $stmt->bind_param("ii", $d_end, $d_start);
}
$stmt->execute();
$chk = $stmt->num_rows;
  • 时间有效性校验:原代码仅校验了datetime_start,补充校验datetime_end可避免无效时间导致的逻辑异常。

内容的提问来源于stack exchange,提问作者Jonjon Castilleja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:25:53