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

PHP账单编号自动生成功能新年失效问题求助

问题根源

问题出在字符串排序逻辑上:
账单号是字符串类型,执行ORDER BY patientno DESC时,数据库会按字符ASCII值排序。2023年12月的账单号(如L5-1223-9999)中,12的首字符1比2024年1月账单号01的首字符0大,因此字符串排序后,2023年12月的编号始终排在2024年1月编号前面。

每次生成新编号时,取到的lastid都是2023年12月的最大编号,此时判断substr($lastid, $CIcnt + 1, 2) != $month(即12 != 01)成立,就会触发新序列分支生成0001,循环往复导致序列号无法递增。

修复方案

最可靠的解决方式是仅查询当前年月对应的账单号,确保拿到当月的最大序列号,而非历史所有编号的最大值。修改后的代码如下:

$CI = "L5"; //Example only
$CIcnt = strlen($CI);
$offset = $CIcnt + 6;

// 获取当前年月的两位字符串
$month = date("m"); // e.g. 09 
$year = date("y"); // e.g. 23  
$currentYearMonth = "$month$year";

// 修改查询:只查当前年月的账单号,取最新的一条
$query = "SELECT patientno FROM iap2 
          WHERE patientno LIKE ? 
          ORDER BY patientno DESC LIMIT 1";
// 用预处理语句避免SQL注入
$stmt = mysqli_prepare($con, $query);
$likePattern = "$CI-$currentYearMonth-%";
mysqli_stmt_bind_param($stmt, "s", $likePattern);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);

$row = mysqli_fetch_assoc($result); 
$lastid = $row['patientno'] ?? null;     

// 判断是否需要开启新序列
if(empty($lastid)) { 
    $number = "$CI-$month$year-0001"; 
} else { 
    // 递增序列号
    $idd = substr($lastid, $offset); 
    $id = str_pad((int)$idd + 1, 4, 0, STR_PAD_LEFT); 
    $number = "$CI-$month$year-$id"; 
} 
额外优化说明
  • 显式强制类型转换:给$idd加上(int),避免字符串转整数的潜在问题,逻辑更严谨。
  • 预处理语句:避免SQL注入风险,尤其当$CI可能来自用户输入时。
  • 空值处理:用?? null确保无数据时$lastid为null,避免未定义索引警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:57:21