最直接方式是array_chunk():按固定长度切分一维数组为二维,每块元素数为正整数,末块不满也保留;手动循环适用于按值分组;array_map+array_slice适合行列转置;禁用array_merge_recursive。

用 array_chunk() 按固定长度切分最直接
PHP 里把一维数组转成二维,最常用也最稳妥的方式就是 array_chunk()。它按指定数量把原数组“切成”多个子数组,每个子数组就是二维结构中的一行。
比如你有一组 ID:[1, 2, 3, 4, 5, 6],想每 2 个一组变成二维:
$ids = [1, 2, 3, 4, 5, 6]; $result = array_chunk($ids, 2); // 得到 [[1,2], [3,4], [5,6]]
- 第二个参数是每块元素个数,必须是正整数,传 0 或负数会报 Warning:“Chunk size must be greater than 0”
- 最后一块可能不满,
array_chunk()默认保留它(不丢弃),这是预期行为,不是 bug - 如果原数组为空,返回空数组
[],不是[[]]
手动循环拼装适合带逻辑的分组
当分组规则不是简单“每 N 个一组”,而是依赖值本身(比如按用户类型归类、按时间戳区间合并),就不能靠 array_chunk(),得手写循环。
常见场景:把扁平的订单数据按 user_id 归集:
$orders = [
['id'=>1, 'user_id'=>101, 'amount'=>99],
['id'=>2, 'user_id'=>102, 'amount'=>120],
['id'=>3, 'user_id'=>101, 'amount'=>88],
];
$grouped = [];
foreach ($orders as $order) {
$uid = $order['user_id'];
if (!isset($grouped[$uid])) {
$grouped[$uid] = [];
}
$grouped[$uid][] = $order;
}
// $grouped[101] 是包含两条记录的数组
- 注意用
isset()判断键是否存在,别直接用!empty()——空数组也会被判定为 false - 这种写法生成的是关联二维结构(键是 user_id),不是纯数字索引;如需转成数字索引,最后套一层
array_values() - 如果原始数据量大(比如上万条),反复
[] =追加在 PHP 7.4+ 性能尚可,但 PHP 8.0+ 更推荐预分配数组大小(不过多数业务场景没必要)
用 array_map + array_slice 实现“跳步取值”式分组
有些需求不是顺序切块,而是按步长抽样重组,比如把一维数组按列优先方式转成 m×n 矩阵(类似 Excel 转置)。
例如原数组有 12 个元素,想转成 3 行 × 4 列:
$data = range(1, 12); $rows = 3; $cols = 4; $result = []; for ($i = 0; $i
-
array_slice()的第三个参数不能省略,否则会从起点截到末尾,导致后续行重复或越界 - 务必先校验
count($data) >= $rows * $cols,否则最后一行可能为空或元素不足 - 这种写法和
array_chunk()表面结果一样,但语义不同:前者强调“行数固定”,后者强调“每块大小固定”——选哪个取决于你的业务变量是“要几行”还是“每行几个”
避免用 array_merge_recursive 处理一维转二维
有人看到“合并数组”就下意识翻出 array_merge_recursive(),但它完全不适合这个任务:它只对**已有二维(及以上)结构**做递归合并,对一维输入只会原样返回,甚至可能意外覆盖键名。
- 传入
[1,2,3]给array_merge_recursive(),返回还是[1,2,3],不会变二维 - 如果你误传了带字符串键的一维数组,比如
['a'=>1, 'b'=>2],它也不会帮你分组,反而可能在深层合并时引发键冲突 - 真正需要
array_merge_recursive()的场景是合并两个结构相似的配置数组,不是数据形态转换
真要强行用它“造”二维,得先手动包一层,比如 array_merge_recursive([], [$arr]),但这属于绕路且易读性差,毫无必要。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











