...this WAS fun. I decided to replicate the desired output as raw text rather than html as a personal challenge.
Essentially, the data is formed into reference arrays, then imploded or iterated print the desired crosstab layout. The $columnWidth
variable allows the whole table to be easily re-sized. str_pad()
is used for center alignment. The null coalescing operator (??
) is used to fallback to -
when a respective value does not exist.
Code: (Demo)
//It is assumed that the sql is perfectly capable of sorting by date ASC, role ASC, name ASC
$resultSet = [
['date' => '01/02/14', 'role' => 'Leader', 'name' => 'Jerry'],
['date' => '01/02/14', 'role' => 'Musician', 'name' => 'Bob'],
['date' => '01/02/14', 'role' => 'Singer', 'name' => 'Carol'],
['date' => '08/02/14', 'role' => 'Leader', 'name' => 'Baz'],
['date' => '08/02/14', 'role' => 'Leader', 'name' => 'Gaz'],
['date' => '08/02/14', 'role' => 'Leader', 'name' => 'Haz'],
['date' => '08/02/14', 'role' => 'Musician', 'name' => 'Charles'],
['date' => '08/02/14', 'role' => 'Singer', 'name' => 'Norman'],
['date' => '15/02/14', 'role' => 'Astronaut', 'name' => 'Neil'],
];
$columnWidth = 20;
foreach ($resultSet as ['date' => $date, 'role' => $role, 'name' => $name]) {
$nested[$date][$role][] = $name;
$dates[$date] = str_pad($date, $columnWidth, " ", STR_PAD_BOTH);
$roles[$role] = str_pad($role, $columnWidth, " ", STR_PAD_BOTH);
}
$totalColumns = count($dates) + 1;
// HEADINGS
printf(
implode("|", array_fill(0, $totalColumns, '%s')) . "\n",
str_pad('Roles', $columnWidth, " ", STR_PAD_BOTH),
...array_values($dates)
);
// SEPARATOR
echo implode("|", array_fill(0, $totalColumns, str_repeat('=', $columnWidth)));
// DATA
foreach ($roles as $role => $paddedRole) {
echo "\n$paddedRole";
foreach ($nested as $date => $roleGroup) {
echo '|' . str_pad(implode(', ', $nested[$date][$role] ?? ['-']), $columnWidth, " ", STR_PAD_BOTH);
}
}
Output:
Roles | 01/02/14 | 08/02/14 | 15/02/14
====================|====================|====================|====================
Leader | Jerry | Baz, Gaz, Haz | -
Musician | Bob | Charles | -
Singer | Carol | Norman | -
Astronaut | - | - | Neil