phphtmlpivot

How to arrange data fetched from mysql as per columns in html table?


I have data from mysql coming in this format (The term goes upto 9 and course could be more in a Term. The assessed column could have an empty value or single value):

Term Course ASSESSED
1 SCIENCE-100
1 STEM-200 BC
2 ASP-400 AB
3 LEV-100 CD
3 WEL-200 AB

I want to show this table in the following table format using PHP:

Term 1 2 3
Course SCIENCE-100 ASP-400 (AB) LEV-100 (CD)
STEM-200 (BC) WEL-200 (AB)

I am using following PHP script to get desirable results but all it does is put everything into one column:

Here, semester is an array of Term, course is an array of course and level is an array of assessed.

$j=1;
for ($i = 0; $i < $size; $i++){
if($semester[$i] == $semester[$j]){
echo $semester[$i];
echo $semester[$j];
echo '<td>'.$courses[$i]." ".$level[$i].'</td></tr>';
}
else
{
echo'<tr>';
echo'<td>'.$courses[$i]." ".$level[$i].'</td>';
echo'</tr>';
}
$j++;
}

Solution

  • A simple approach would be to first group the courses by terms in a 2D array: first dimension is the term, second dimension represents courses of each term

    $groupedByTerm = [];
    foreach ($courses as $course) {
        if (! isset($groupedByTerm[$course['term']])) {
            $groupedByTerm[$course['term']] = [];
        }
        $groupedByTerm[$course['term']][] = $course['course'];
    }
    

    So the snippet above would transform an initial array represented like this:

    // representation of the $courses array
    [
        ['term' => 1, 'course' => 'Course A'],
        ['term' => 1, 'course' => 'Course B'],
        ['term' => 2, 'course' => 'Course C'],
        ['term' => 3, 'course' => 'Course D'],
        ['term' => 3, 'course' => 'Course E'],
    ];
    

    into this

    // representation of the $groupedByTerm array after running the snippet
    [
        1 => ['Course A', 'Course B'],
        2 => ['Course C'],
        3 => ['Course D', 'Course E'],
    ];
    
    

    Then, for building a table,using the data structure above, you will loop until all the terms are empty, which can be done with a do-while that will complete when all the arrays for each terms are empty:

    $row = 0;
    $row = 0;
    do {
        $hasData = false;
        echo '<tr>';
        if ($row == 0) {
            echo '<td>Course</td>';
        } else {
            echo '<td></td>';
        }
        foreach ($groupedByTerm as $term) {
            echo '<td>';
            if (is_array($term) && isset($term[$row])) {
                $hasData = true;
                echo $term[$row];
            }
            echo '</td>';
        }
        echo '</tr>';
        $row++;
    
    } while($hasData);
    

    The implementation above is what would render the body of the table. I simply use echo statements but you could accumulate the string in a variable.