
在web开发中,我们经常需要将后端获取的数据以表格形式展示给用户。然而,当数据存在一对多关系时(例如,一个用户在同一天访问了多个地点),直接遍历原始数组可能会导致重复显示关键信息,如用户姓名和日期,使得表格冗余且不易阅读。
考虑以下原始PHP数组结构,其中包含了用户ID、地点ID、姓名、地点和日期信息:
$arr =
[
[
'user_id' => 5,
'l_id' => 10,
'Name' => 'John Doe',
'Location' => 'Chicago',
'date' => '2021-10-02'
],
[
'user_id' => 5,
'l_id' => 11,
'Name' => 'John Doe',
'Location' => 'Houston',
'date' => '2021-10-02'
],
[
'user_id' => 6,
'l_id' => 12,
'Name' => 'Rob Doe',
'Location' => 'Dallas',
'date' => '2021-10-02'
],
[
'user_id' => 6,
'l_id' => 13,
'Name' => 'Rob Doe',
'Location' => 'Philadelphia',
'date' => '2021-10-02'
],
];如果直接使用简单的循环生成HTML表格,结果会是:
| Name | Date | Location |
|---|---|---|
| John Doe | 2021-10-02 | Chicago |
| John Doe | 2021-10-02 | Houston |
| Rob Doe | 2021-10-02 | Dallas |
| Rob Doe | 2021-10-02 | Philadelphia |
这与我们期望的输出不同。我们希望将同一用户在同一天的所有地点信息聚合到一个单元格中,使表格更加紧凑和直观:
| Name | Date | Location |
|---|---|---|
| John Doe | 2021-10-02 | Chicago Houston |
| Rob Doe | 2021-10-02 | Dallas Philadelphia |
要实现上述目标,核心思想是先对原始数据进行重构,将其转换为更适合分组展示的层级结构,然后再根据新结构生成HTML。
立即学习“PHP免费学习笔记(深入)”;
我们需要一个函数来遍历原始数组,并根据user_id进行分组。对于每个用户,我们将收集其所有的地点信息到一个子数组中。
/**
* 将扁平的用户位置数组重构为按用户分组的层级数组。
*
* @param array $oldArray 原始的用户位置数据数组。
* @return array 重构后的数组,以user_id为键,每个元素包含用户信息及所有相关位置。
*/
function arrayChanger(array $oldArray): array
{
$newArray = [];
foreach ($oldArray as $record) {
// 如果该user_id尚未在newArray中,则初始化其结构
if (!isset($newArray[$record['user_id']])) {
$newArray[$record['user_id']] = [
'user_id' => $record['user_id'],
'Name' => $record['Name'],
'date' => $record['date'],
'UserLocations' => [] // 用于存储该用户的所有位置信息
];
}
// 将当前记录的位置信息添加到对应用户的UserLocations数组中
$newArray[$record['user_id']]['UserLocations'][] = [
'Location' => $record['Location'],
];
}
return $newArray;
}函数说明:
经过 arrayChanger($arr) 处理后,我们的数据结构将大致变为:
[
5 => [
'user_id' => 5,
'Name' => 'John Doe',
'date' => '2021-10-02',
'UserLocations' => [
['Location' => 'Chicago'],
['Location' => 'Houston']
]
],
6 => [
'user_id' => 6,
'Name' => 'Rob Doe',
'date' => '2021-10-02',
'UserLocations' => [
['Location' => 'Dallas'],
['Location' => 'Philadelphia']
]
]
]这种结构使得我们可以在外层循环中一次性获取用户姓名和日期,然后在内层循环中遍历并聚合其所有位置信息。
有了重构后的数据,生成符合要求的HTML表格就变得简单了。我们只需要遍历重构后的数组,对于每个用户记录,生成一行 <tr>。在该行中,用户姓名和日期各占一个 <td>,而所有位置信息则通过内循环拼接,并用 <br> 换行符分隔,放入同一个“Location” <td> 中。
// 假设 $arr 是上面定义的原始数组
$processedData = arrayChanger($arr);
$html = '<table>
<thead>
<tr>
<th>Name</th>
<th>Date</th>
<th>Location</th>
</tr>
</thead>
<tbody>';
foreach ($processedData as $userRecord) {
$html .= '<tr>';
$html .= '<td>' . htmlspecialchars($userRecord['Name']) . '</td>';
$html .= '<td>' . htmlspecialchars($userRecord['date']) . '</td>';
$html .= '<td>';
// 遍历该用户的所有位置信息,并用 <br> 连接
foreach ($userRecord['UserLocations'] as $locationItem) {
$html .= htmlspecialchars($locationItem['Location']) . "<br>";
}
// 移除最后一个 <br>,避免多余的换行
$html = rtrim($html, '<br>');
$html .= '</td>';
$html .= '</tr>';
}
$html .= '</tbody>
</table>';
echo $html;代码说明:
将上述数据定义、数据重构函数和HTML生成逻辑整合在一起,即可得到完整的解决方案:
<?php
$arr =
[
[
'user_id' => 5,
'l_id' => 10,
'Name' => 'John Doe',
'Location' => 'Chicago',
'date' => '2021-10-02'
],
[
'user_id' => 5,
'l_id' => 11,
'Name' => 'John Doe',
'Location' => 'Houston',
'date' => '2021-10-02'
],
[
'user_id' => 6,
'l_id' => 12,
'Name' => 'Rob Doe',
'Location' => 'Dallas',
'date' => '2021-10-02'
],
[
'user_id' => 6,
'l_id' => 13,
'Name' => 'Rob Doe',
'Location' => 'Philadelphia',
'date' => '2021-10-02'
],
];
/**
* 将扁平的用户位置数组重构为按用户分组的层级数组。
*
* @param array $oldArray 原始的用户位置数据数组。
* @return array 重构后的数组,以user_id为键,每个元素包含用户信息及所有相关位置。
*/
function arrayChanger(array $oldArray): array
{
$newArray = [];
foreach ($oldArray as $record) {
if (!isset($newArray[$record['user_id']])) {
$newArray[$record['user_id']] = [
'user_id' => $record['user_id'],
'Name' => $record['Name'],
'date' => $record['date'],
'UserLocations' => []
];
}
$newArray[$record['user_id']]['UserLocations'][] = [
'Location' => $record['Location'],
];
}
return $newArray;
}
$processedData = arrayChanger($arr);
$html = '<table>
<thead>
<tr>
<th>Name</th>
<th>Date</th>
<th>Location</th>
</tr>
</thead>
<tbody>';
foreach ($processedData as $userRecord) {
$html .= '<tr>';
$html .= '<td>' . htmlspecialchars($userRecord['Name']) . '</td>';
$html .= '<td>' . htmlspecialchars($userRecord['date']) . '</td>';
$html .= '<td>';
// 收集所有位置到一个临时数组,然后用 implode 连接
$locations = [];
foreach ($userRecord['UserLocations'] as $locationItem) {
$locations[] = htmlspecialchars($locationItem['Location']);
}
$html .= implode('<br>', $locations);
$html .= '</td>';
$html .= '</tr>';
}
$html .= '</tbody>
</table>';
echo $html;
?>运行上述代码,将生成如下HTML结构,并在浏览器中呈现出我们期望的表格样式:
<table>
<thead>
<tr>
<th>Name</th>
<th>Date</th>
<th>Location</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>2021-10-02</td>
<td>Chicago<br>Houston</td>
</tr>
<tr>
<td>Rob Doe</td>
<td>2021-10-02</td>
<td>Dallas<br>Philadelphia</td>
</tr>
</tbody>
</table>本教程详细阐述了如何在PHP中通过数据重构,将扁平化的数组数据转换为适合分组展示的层级结构,并以此生成美观且易读的HTML表格。这种方法有效地解决了同一字段重复显示的问题,提升了数据展示的效率和用户体验。掌握这种数据预处理技巧,对于处理复杂数据展示需求至关重要。
以上就是PHP数据重构与HTML表格分组显示教程的详细内容,更多请关注php中文网其它相关文章!
HTML怎么学习?HTML怎么入门?HTML在哪学?HTML怎么学才快?不用担心,这里为大家提供了HTML速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号