前端渲染「每行 N 個項目」(如商品網格、圖片牆)時,常需將一維陣列切割為二維陣列:[ [item1..N], [itemN+1..2N], ... ]。本文提供通用 PHP 切割函數、Smarty/Blade 模板渲染範例,並說明邊界情況處理。
/**
* 將一維陣列按固定大小切割為二維陣列
* @param array $flat 來源陣列
* @param int $chunkSize 每組筆數
* @return array 二維陣列
*/
function chunk_array(array $flat, int $chunkSize): array {
if ($chunkSize <= 0) throw new InvalidArgumentException('chunkSize 必須 > 0');
$result = [];
$group = [];
$i = 0;
foreach ($flat as $item) {
$group[] = $item;
if (++$i === $chunkSize) {
$result[] = $group;
$group = [];
$i = 0;
}
}
if ($group) $result[] = $group; // 餘數組
return $result;
}
// 使用範例
$arr = [1,2,3,4,5,6,7];
$data = chunk_array($arr, 4);
// 結果:[[1,2,3,4], [5,6,7]]
<ul>
{foreach from=$data item=group}
<li>
{foreach from=$group item=val}
<a href="#"><img src="{$val.image_url}" alt="{$val.name}"></a>
{/foreach}
</li>
{/foreach}
</ul>
<ul>
@foreach ($data as $group)
<li>
@foreach ($group as $val)
<a href="#"><img src="{{ $val['image_url'] }}" alt="{{ $val['name'] }}"></a>
@endforeach
</li>
@endforeach
</ul>
<ul>
<?php foreach ($data as $group): ?>
<li>
<?php foreach ($group as $val): ?>
<a href="#"><img src="<?= htmlspecialchars($val['image_url']) ?>" alt="<?= htmlspecialchars($val['name']) ?>"></a>
<?php endforeach; ?>
</li>
<?php endforeach; ?>
</ul>
function chunk_array_preserve_keys(array $flat, int $chunkSize): array {
$result = [];
$group = [];
$i = 0;
foreach ($flat as $k => $v) {
$group[$k] = $v;
if (++$i === $chunkSize) {
$result[] = $group;
$group = [];
$i = 0;
}
}
if ($group) $result[] = $group;
return $result;
}
$data = array_chunk($arr, 4, true); // 第三參數 true 保留鍵名
// 注意:array_chunk 會重新索引數字鍵,關聯鍵需 true 保留
function chunk_paginate(array $flat, int $chunkSize, int $page, int $groupsPerPage): array {
$allGroups = chunk_array($flat, $chunkSize);
$offset = ($page - 1) * $groupsPerPage;
return array_slice($allGroups, $offset, $groupsPerPage);
}
| 問題 | 原因 | 解決 |
|---|---|---|
| 最後一組筆數不足 | 總筆數非 chunkSize 倍數 | 正常現象,模板需支援可變長度迴圈 |
| 鍵名遺失 | array_chunk 預設重新索引 | 傳第三參數 true 或用自定義函數 |
| 記憶體飆升 | 原陣列極大(百萬級) | 改用 Generator 分塊輸出,或資料庫 LIMIT 分頁 |
| 模板報錯「Invalid argument supplied for foreach」 | $data 為 null 或非陣列 | 函數回傳前確保 `return $result ?: [[]]` |
掌握 chunk_array 核心邏輯與 array_chunk 內建函數差異,即可靈活應對各類「固定列數網格」渲染需求。建議封裝為專案通用 Helper 函數,統一參數驗證與邊界處理。