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
相关产品推荐
相关产品推荐

