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

PHP开发问题:数据库CF_PROCUREMENT表TENDER_DEADLINE_PROC字段与当前时间对比异常排查

问题排查与修复方案

咱们一步步拆解你遇到的问题,核心原因有几个,我帮你逐个理清:

1. 最致命的问题:未获取查询结果行

你用sqlsrv_has_rows($result)判断了表中有匹配数据,但根本没从结果集中取出具体的行数据!$row变量完全是未定义状态,这时候new DateTime($row['TENDER_DEADLINE_PROC'])要么报错,要么会因为传入空值创建一个代表当前时间的DateTime对象——这就导致你实际上在拿两个当前时间做对比,自然逻辑完全错乱。

2. 用字符串对比日期完全不可靠

你把DateTime对象转成了d/m/Y H:i:s和d/m/Y格式的字符串,然后用>比较。字符串对比是按字符顺序逐位判断的,比如05/10/2024和10/09/2024,字符串会认为前者更小,但实际日期前者是10月5日,比9月10日晚。这种方式完全不能用来判断时间先后。

3. 额外风险:SQL注入漏洞

你直接把$code拼进SQL语句里,这是非常危险的做法,很容易被攻击者利用注入攻击,必须改成参数化查询。


修复后的完整代码

我把这些问题都修正了,你可以参考:

// 改用参数化查询,避免SQL注入
$sql = "SELECT * FROM CF_PROCUREMENT WHERE CASEFOLDERID = ?";
$params = array($code);
$result = sqlsrv_query($db, $sql, $params);

if ($result) {
    // 取出结果行(这里假设只需要匹配的第一行数据)
    $row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC);
    if ($row) {
        // 先检查字段是否有值,避免DateTime构造报错
        if (!empty($row['TENDER_DEADLINE_PROC'])) {
            // 直接用DateTime对象对比,不需要转字符串
            $deadline = new DateTime($row['TENDER_DEADLINE_PROC']);
            $now = new DateTime();
            
            // 这里调整了逻辑:截止日期早于当前时间,才说明已过期发提醒
            // 你原代码的逻辑是反过来的,注意确认需求
            if ($deadline < $now) {
                $mail->Subject = 'PORTAL Deadline Alert';
                $mail->Body = '<html><body><h1>Deadline has lapsed</h1></body></html>';
                $mail->send();
            } else {
                $mail->Subject = 'PORTAL Email Verification';
                $mail->Body = "<html><body><h1>VERIFICATION CODE</h1><h2>Code: <b>$otp_code</b></h2></body></html>";
            }
        } else {
            // 如果截止日期字段为空,这里可以加默认处理逻辑,比如直接发验证码
            $mail->Subject = 'PORTAL Email Verification';
            $mail->Body = "<html><body><h1>VERIFICATION CODE</h1><h2>Code: <b>$otp_code</b></h2></body></html>";
        }
    }
}

额外说明

  • 我调整了你原代码的判断逻辑:原代码写的是$date > $now时发过期提醒,但实际应该是截止日期早于当前时间才是过期状态,你可以根据实际需求再确认。
  • 如果你的TENDER_DEADLINE_PROC字段是SQL Server的datetime类型,sqlsrv_fetch_array可能会直接返回DateTime对象(取决于驱动配置),这时候可以不用手动创建DateTime对象,直接用$row['TENDER_DEADLINE_PROC']对比就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 10:47:29