
本文详解如何使用 php 的 while 循环结合取模运算,精准控制每行输出 3 个或 4 个数字(交替为“3列→4列→3列→4列”),生成指定格式的网格化数字列表。
要实现如下目标输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
关键在于:每行元素数量按 3 → 4 → 3 → 4 循环变化,共 14 个数字(1 到 14)。这并非简单的“每 3 或每 4 换行”,而是基于当前数字位置决定该数是否为某行的末尾——即需判断「第几个数字」应触发换行。
✅ 正确思路:用序号对周期取模判定换行点
观察目标结构中各数字后是否换行:
| $i | 输出后是否换行 | 理由 |
|---|---|---|
| 3 | 是 | 第 1 行末(3 个) |
| 7 | 是 | 第 2 行末(+4 = 7) |
| 10 | 是 | 第 3 行末(+3 = 10) |
| 14 | 是 | 第 4 行末(+4 = 14) |
可见换行位置为:$i = 3, 7, 10, 14。这些数满足一个规律:
? 当 $i % 7 == 0 或 $i % 7 == 3 时换行(因为 7 是 3+4 的周期长度;3 是第一段长度)。
? 验证:3 % 7 = 3 → 换行 ✅7 % 7 = 0 → 换行 ✅10 % 7 = 3 → 换行 ✅14 % 7 = 0 → 换行 ✅
因此,可使用 while 循环 + 取模条件精准控制:
立即学习“PHP免费学习笔记(深入)”;
";
} else {
echo " ";
}
$i++;
}
?>✅ 输出完全符合要求:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
⚠️ 原代码问题分析
原始代码存在两个关键错误:
- while($i=1
- 逻辑未关联“行结构”,仅用 $i
? 扩展建议:封装为可复用函数
若需适配不同范围或自定义行列模式(如 2:5 或 4:4),推荐封装为函数:
function renderGrid($start, $end, $pattern = [3, 4]) {
$i = $start;
$pos = 0; // 当前在 pattern 中的位置
$cumulative = 0; // 累计到当前 pattern 段的总长度
while ($i <= $end) {
echo $i;
$cumulative++;
// 若到达当前 pattern 段的长度,则换行并重置累计值
if ($cumulative == $pattern[$pos]) {
echo "
";
$cumulative = 0;
$pos = ($pos + 1) % count($pattern);
} else {
echo " ";
}
$i++;
}
}
// 调用:1~14,按 [3,4] 交替
renderGrid(1, 14, [3, 4]);✅ 总结
- 实现非等宽网格的核心是将行结构建模为周期性规则,而非硬编码分支;
- modulo (%) 是检测周期位置最简洁高效的方式;
- while 完全可用,但需确保循环变量正确递增、终止条件严谨;
- 生产环境中建议添加边界校验(如 $start
掌握此模式,即可灵活生成任意行列比(如新闻列表的 Masonry 前置布局、仪表盘卡片分组等)的 PHP 后端结构化输出。











