在PHP foreach循环中对项目进行分组[关闭]

I want somehow to group items in foreach loop so i can display them effectively. For example if I have the following MySql table:

user_id username group_id
1       John     1
2       Mark     2
3       Steve    2

I want the users in the group_id 2 to be shown together in <div class="group2">Username 1: Mark, Username 2: Steve</div> and users in group_id 1 <div class="group1">Username John</div>

I hope you will understand the question.

You can do this fairly easily by ordering your query by group_id and then keeping track of when it changes. Something like this:

$query = "SELECT * FROM table ORDER BY group_id";
$results = $mysqli->query($query);
$lastGroup = 0;
while ( $row = $results->fetch_assoc() )
{
    if ( $row['group_id'] != $lastGroup )
    {
        // If there is already a div open we need to close it, so if 
        // last group > 0 then a div has been opened.
        echo ($lastGroup > 0 ? '</div>' : '') . '<div class="group' . $row['group_id'] . '">';
    }
    $lastGroup = $row['group_id'];
    echo $row['username'] . '<br>';
}
// close the last open div
echo '</div>';

Alternatively you can use the MySQL GROUP_CONCAT function to get back all the usernames in a group. Use this:

$query = "SELECT group_id,
GROUP_CONCAT(username) as users
FROM table
GROUP BY group_id";

$results = $mysqli->query($query);
while ( $row = $results->fetch_assoc() )
{
    echo '<div class="group' . $row['group_id'] . '">' . $row['users'] . '</div>';
}

Create a 2D array:

$users;

Foreach results row $row:

$users[$row->group_id][$row->user_id] = $row->username;

Then:

foreach($users as $group_id -> $group_users) {
    echo '<div class="' . $group_id . '">';
    foreach($group_users as $user_id -> $username) {
        echo " Username: ";
        echo $user_id;
        echo " :";
        echo $username;
    }
    echo "</div>";
}
It is highly recommended to craft your query using mysql GROUPing function so you don't have to do this mechanically. However, if for any reason, you have a result-set that looks like the data you posted and you want to loop through then and display the record as you described; You could walk the array of your rows, bundling all users in the same group to a unique sub-array and afterwards run a foreach loop for the display. The Code below demonstrates how with an example:
    <?php

        // SIMULATE AN TO REPRESENT THE RECORDS FROM THE DB TABLE...
        $array = array(
            array(
                "user_id"   => 1,
                "username"  => "John",
                "group_id"  => 1,
            ),
            array(
                "user_id"   => 2,
                "username"  => "Mark",
                "group_id"  => 2,
            ),
            array(
                "user_id"   => 2,
                "username"  => "Steve",
                "group_id"  => 2,
            ),
        );

        // CREATE AN ARRAY FOR USE IN GROUPING USERS WITH THE SAME group_id
        $groupArray = array();

        // WALK THE SIMULATED ARRAY (IN YOUR CASE YOUR ROWS)
        // AND BUILD UP THE $groupArray
        $result     = array_walk($array, function($data) use(&$groupArray) {
            if(!array_key_exists($data['group_id'], $groupArray)){
                $groupArray[$data['group_id']][]        = $data;
            }else{
                if(!in_array($data, $groupArray)){
                    $groupArray[$data['group_id']][]    = $data;
                }
            }
        });

        // CREATE AN OUTPUT TO HOLD THE HTML CONTENT FOR DISPLAY:
        $output     = "";

        // LOOP THROUGH THE $groups AND BUILD UP YOUR DATA...
        foreach ($groupArray as $groupID=>$groups){
            $output.= "<div class='group" . $groupID . "'>" . PHP_EOL;
            $output.= "<h3 class='group-users'>Users in Group {$groupID}</h3>" . PHP_EOL;

            foreach($groups as $group){
                $output.= "<span class='user-name'>Username: " . $group['user_id'] . ": {$group['username']},</span><br />" . PHP_EOL;
            }
            $output.= "</div>" . PHP_EOL;
        }


        var_dump($output);
        // echo $output;



        // THE var_dump($output) PRODUCES::         
        string '<div class='group1'>
                    <h3 class='group-users'>Users in Group 1</h3>
                    <span class='user-name'>Username: 1: John,</span><br />
                </div>
                <div class='group2'>
                <h3 class='group-users'>Users in Group 2</h3>
                    <span class='user-name'>Username: 2: Mark,</span><br />
                    <span class='user-name'>Username: 2: Steve,</span><br />
                </div>
                ' (length=317)