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 usingmysql 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 aforeach
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)