PHP按日期范围循环写入数据库出现日期偏移问题求解
问题原因
日期偏移是代码执行顺序和mysqli绑定机制共同导致的:
- mysqli的
bind_param是引用绑定,绑定的是变量本身而非绑定时刻的变量值,执行SQL时会读取变量当前的最新值 - 循环逻辑顺序错误:在绑定变量后、执行插入前,就先对
$DIACOMIENZO做了+1天的修改,导致第一次插入时取到的已经是起始日期+1天的值 - 最后一轮循环时,当
$DIACOMIENZO等于结束日期,依然会先把日期+1天再执行插入,最终多插入了结束日期+1天的记录,完全匹配你遇到的偏移结果。
另外原有代码还存在日期解析隐患:strtotime默认将斜杠分隔的日期解析为美式m/d/Y(月/日/年)格式,如果你表单传入的是d/m/Y(日/月/年)格式的日期,会直接出现日期解析错误。
正确实现方案
做三处调整即可:
- 用
DateTime类指定格式解析传入的起止日期,彻底避免格式解析歧义 - 把SQL预处理逻辑放到循环外,减少重复编译提升性能
- 调整循环内执行顺序:先插入当前日期,插入完成后再做日期递增,避免引用绑定导致的值错乱
修复后代码:
<?php require('db.php'); if (isset($_REQUEST['DIACOMIENZO'])){ // 按实际传入的日期格式修改第一个参数,d/m/Y对应日/月/年,m/d/Y对应月/日/年 $startDate = DateTime::createFromFormat('d/m/Y', $_REQUEST['DIACOMIENZO']); $endDate = DateTime::createFromFormat('d/m/Y', $_REQUEST['DIAFIN']); // 修正结束日期时间,避免同一天时间精度问题导致漏判 $endDate->setTime(23, 59, 59); // 预处理语句仅需执行一次 $stmt = $con->prepare("INSERT INTO DIASHORARIOS (DIA) VALUES (?)"); $stmt->bind_param("s", $insertDate); $currentDate = clone $startDate; while ($currentDate <= $endDate) { $insertDate = $currentDate->format('Y-m-d'); $stmt->execute(); // 先执行插入当前日期 $currentDate->modify('+1 day'); // 插入完成后再递增到下一天 } $stmt->close(); } ?>
如果你的数据库字段存的是
d/m/Y格式的字符串,只需要把$currentDate->format('Y-m-d')里的格式串改成d/m/Y即可。
内容的提问来源于stack exchange,提问作者vLife
相关产品推荐
相关产品推荐

