後台管理列表、商品展示墻、圖片畫廊等常需將一維數據按固定列數「橫向排列」輸出 HTML 表格。例如:每行顯示 3 個產品,共 11 條記錄 → 4 行 (3+3+3+2)。
<?php
// 模擬數據
$items = range(1, 11); // [1,2,3,4,5,6,7,8,9,10,11]
$cols = 3; // 每行列數
echo '<table border="1"><tr>';
foreach ($items as $index => $value) {
// 關鍵邏輯:索引能被列數整除時,閉合上一行並開啟新行
// 注意:$index 從 0 開始,第一個元素 (index=0) 觸發換行會產生空行
// 修正:($index % $cols === 0) && $index !== 0
if ($index !== 0 && $index % $cols === 0) {
echo '</tr><tr>';
}
echo "<td>$value</td>";
}
// 填充最後一行不足的單元格 (可選,保持表格結構完整)
$remainder = count($items) % $cols;
if ($remainder !== 0) {
echo str_repeat('<td> </td>', $cols - $remainder);
}
echo '</tr></table>';
/**
* 將一維數組渲染為多行多列 HTML 表格
* @param array $data 數據數組 (鍵值對或純值)
* @param int $cols 每行列數
* @param callable $cellRenderer 單元格渲染回調 fn($key, $value) : string
* @param array $tableAttrs table 標屬性 ['class'=>'table', 'border'=>1]
* @return string HTML 字符串
*/
function render_grid_table(array $data, int $cols, callable $cellRenderer, array $tableAttrs = []): string {
if ($cols < 1) throw new InvalidArgumentException('列數必須 > 0');
$attrs = '';
foreach ($tableAttrs as $k => $v) $attrs .= " $k=\"".htmlspecialchars($v)."\"";
$html = "<table$attrs><tr>";
$count = count($data);
foreach ($data as $key => $value) {
$index = array_search($key, array_keys($data)); // 獲取數字索引
if ($index !== 0 && $index % $cols === 0) {
$html .= '</tr><tr>';
}
$html .= '<td>' . $cellRenderer($key, $value) . '</td>';
}
// 填充空單元格
$remainder = $count % $cols;
if ($remainder !== 0) {
$html .= str_repeat('<td> </td>', $cols - $remainder);
}
$html .= '</tr></table>';
return $html;
}
// 使用示例:商品列表
$products = [
101 => ['name'=>'iPhone 15', 'price'=>5999, 'img'=>'p1.jpg'],
102 => ['name'=>'MacBook Air', 'price'=>7999, 'img'=>'p2.jpg'],
// ...
];
echo render_grid_table($products, 4, function($id, $p) {
return "<img src='{$p['img']}' width='120'><br>{$p['name']}<br><b>¥{$p['price']}</b>";
}, ['class'=>'product-grid']);
表格佈局語義不純、響應式困難。現代 CSS 只需將數據渲染為扁平列表,交由樣式控制換行:
<div class="grid">
<?php foreach ($products as $p): ?>
<div class="card">
<img src="<?=$p['img']?>">
<h4><?=$p['name']?></h4>
<span>¥<?=$p['price']?></span>
</div>
<?php endforeach; ?>
</div>
<style>
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; }
.card { border: 1px solid #eee; border-radius: 8px; padding: 12px; text-align: center; }
@media (max-width: 600px) { .grid { grid-template-columns: 1fr; } }
</style>
優勢:無需計算列數、自適應容器寬度、語義清晰、無障礙友好、維護成本極低。
<table> + PHP 取模算法:兼容極老瀏覽器、郵件模板、PDF 生成等受限環境。