PHP按规则生成3位混合序列号 如何指定循环起始位置
PHP 按指定起始位置生成3位混合序列号实现方案
实现逻辑
- 先对传入的起始序列号做格式判断,区分「首字母+两位数字」(A00-Z99)的第一阶段,和「前两位字母+一位数字」(AA0-ZZ9)的第二阶段
- 计算对应阶段的循环起始偏移,直接从指定位置开始生成,无需从头遍历浪费资源
- 调用API后如果返回成功立刻终止所有循环,记录当前序列号供下次启动使用
完整可运行代码
<?php // 可把上次最后生成的序列号存在本地文件/缓存,下次启动直接读这个值当起始位 $startSerial = 'A99'; // 示例起始位置,可替换为BB1等任意符合规则的序列号 $success = false; $serialNo = ''; // 解析起始序列号所属阶段和起始值 $isFirstStage = is_numeric($startSerial[1]); if ($isFirstStage) { // 第一阶段:首字母+两位数字 $startX = $startSerial[0]; $startY = (int)substr($startSerial, 1, 2); } else { // 第二阶段:前两位字母+一位数字 $startX = $startSerial[0]; $startY = $startSerial[1]; $startZ = (int)$startSerial[2]; $firstStageCompleted = true; // 直接跳过第一阶段 } // 第一阶段生成:A00 -> Z99 if (!isset($firstStageCompleted)) { foreach (range('A', 'Z') as $x) { if ($success) break; // 小于起始X的直接跳过 if ($x < $startX) continue; // 确定当前X对应的y起始值 $currentYStart = ($x == $startX) ? $startY : 0; for ($y = $currentYStart; $y < 100; $y++) { if ($success) break; $serialNo = $x . sprintf("%02d", $y); // 这里调用你的共享API,返回true则把$success设为true // $success = callYourApi($serialNo); } } } // 第一阶段遍历完还没成功,进入第二阶段生成:AA0 -> ZZ9 if (!$success) { foreach (range('A', 'Z') as $x) { if ($success) break; // 小于起始X的直接跳过 if (isset($startX) && $x < $startX) continue; // 确定当前X对应的y起始值 $currentYStart = (isset($startX) && $x == $startX) ? $startY : 'A'; foreach (range('A', 'Z') as $y) { if ($success) break; // 小于起始Y的直接跳过 if ($y < $currentYStart) continue; // 确定当前Y对应的z起始值 $currentZStart = (isset($startX) && $x == $startX && $y == $startY) ? $startZ : 0; // 如果你规则要求第二阶段从1开始,把上面0改成1即可 for ($z = $currentZStart; $z < 10; $z++) { if ($success) break; $serialNo = $x . $y . $z; // 这里调用你的共享API,返回true则把$success设为true // $success = callYourApi($serialNo); } // 第一轮Y遍历完后清空起始Y的限制,后续Y从A开始 unset($currentYStart); } // 第一轮X遍历完后清空起始X的限制,后续X从A开始 unset($startX, $startY, $startZ); } } // 执行完后记得把最终的$serialNo存起来,下次启动当起始位用 // file_put_contents('./last_serial.txt', $serialNo); ?>
补充说明
- 如果你需要第二阶段严格按照规则从AA1开始,只需要把代码中第二阶段
$currentZStart的默认值从0改成1即可 - 建议每次执行完脚本把最后生成的序列号存在本地文件或缓存中,下次启动直接读取该值作为起始位,不需要手动输入
- 所有循环都加了提前终止判断,只要API返回成功就会立刻停止所有遍历,不会生成多余的序列号
内容的提问来源于stack exchange,提问作者Alvin Chan
相关产品推荐
相关产品推荐

