Nested for loops results in duplicate entries - php

I have problems with the following code. I get duplicate entries of the content in the database.
I think it has something to do with the for loop, but I don't know how I could correct it.
SQL query:
public function getConfRoomList()
{
$arr = array();
$statement = $this->conn->prepare("SELECT id, name, roomnbr, location, seats, utilities from moterom order by name ASC");
$statement->bind_result($id, $name, $roomnbr, $location, $seats, $utilities);
$statement->execute();
while ($statement->fetch()) {
$arr[] = [ "id" => $id, "name" => $name, "roomnbr" => $roomnbr, "location" => $location, "seats" => $seats, "utilities" => $utilities];
}
$statement->close();
return $arr;
}
public function joinDevRoom()
{
$arr = array();
$statement = $this->conn->prepare("SELECT r.name,GROUP_CONCAT(u.device) FROM moterom r LEFT JOIN utilities u ON FIND_IN_SET(u.id,r.utilities)>0 GROUP BY r.id");
$statement->bind_result($id, $utilities);
$statement->execute();
while ($statement->fetch()) {
$utilities = str_replace(',','<br />',$utilities);
$arr[] = [ "id" => $id, "utilities" => $utilities];
}
$statement->close();
return $arr;
}
public function getDeviceList()
{
$arr = array();
$statement = $this->conn->prepare("SELECT id, device, model, img, supplier from utilities order by device ASC");
$statement->bind_result($id, $device, $model, $img, $supplier);
$statement->execute();
while ($statement->fetch()) {
$arr[] = [ "id" => $id, "device" => $device, "model" => $model, "img" => $img, "supplier" => $supplier];
}
$statement->close();
return $arr;
}
The content:
<?php
require_once("db.php");
$arr = $conn->getConfRoomList();
$join = $conn->joinDevRoom();
$dev = $conn->getDeviceList();
?>
<div class="add_dev_header">Møterom</div>
<?php
if (!empty($arr)) { ?>
<table border='1'>
<tr>
<th>Conference room</th>
<th>Room number</th>
<th>Location</th>
<th>Number of seats</th>
<th>Available utilities</th>
<th>Edit</th>
<th>Delete</th>
</tr>
<?php for( $i=0; $i < count($arr); $i++) {
for( $u=0; $u < count($join); $u++) {
print_r ("<tr>
<td>".$arr[$i]['name']."</td>
<td>".$arr[$i]['roomnbr']."</td>
<td>".$arr[$i]['location']."</td>
<td>".$arr[$i]['seats']."</td>
<td>".$join[$u]['utilities']."</td>
<td><a href='?p=editconfroomv2&id=".$arr[$i]['id']."'>Edit</a></td>
<td><a href='?p=deleteconfroomdb&id=".$arr[$i]['id']."' class='delete'>Delete</a></td>
</tr>"); } } ?>
</table>
<?php } else {
echo "<div id='db_empty'>Database is empty...<br>
You can be the first to <a href='?p=addconfroom'>register a conference room</a>.</div>";
}
?>
I have two rooms and one utility in the databases, and the printed result looks something like this:
Room 1 | Room number 1 | Location 1 | Seats 23 | Gear 1 | Edit | Delete
Room 1 | Room number 1 | Location 1 | Seats 23 | Gear 1 | Edit | Delete
Room 2 | Room number 2 | Location 2 | Seats 6 | Gear 1 | Edit | Delete
Room 2 | Room number 2 | Location 2 | Seats 6 | Gear 1 | Edit | Delete

Related

SQL Split comma separated list from one table and print content from second table based upon this list

I have two tables, rooms and utilities.
In the table named roomsI have a coloumn also called utilities. This coloumn stores comma separated numbers referencing the IDs from the table utilities.
How can I split (explode?) the values from the utilities coloumn, and match them against the utilities table, printing the values that have matching IDs as the spitted values?
Example:
Table: rooms
|---------------|----------------|-----------------|
| ID | Name | Utilities |
|---------------|----------------|-----------------|
| 1 | Room1 | 1,3,4 |
|---------------|----------------|-----------------|
Table: utilities
|---------------|----------------|
| ID | Device |
|---------------|----------------|
| 1 | Speakers |
|---------------|----------------|
| 2 | TV |
|---------------|----------------|
| 3 | Smart TV |
|---------------|----------------|
| 4 |Web camera|
|---------------|----------------|
I want to print something like this:
Room1: Speakers, Smart TV, Web camera
Here's what I have so far, confroomreport.php:
<?php
require_once("db.php");
$util = $conn->getDeviceList();
$arr = $conn->getConfRoomList();
?>
<table border='1'>
<tr>
<th>Room</th>
<th>Utilities</th>
</tr>
<?php for( $i=0; $i < count($arr); $i++) {
print_r ("<tr>
<td>".$arr[$i]['name']."</td>
<td>".$arr[$i]['utilities']."</td>
</tr>"); } ?>
</table>
and in db.php
public function getDeviceList()
{
$arr = array();
$statement = $this->conn->prepare("SELECT id, device from utilities order by device ASC");
$statement->bind_result($id, $device);
$statement->execute();
while ($statement->fetch()) {
$arr[] = [ "id" => $id, "device" => $device];
}
$statement->close();
return $arr;
}
public function getConfRoomList()
{
$arr = array();
$statement = $this->conn->prepare("SELECT id, name, utilities from rooms order by name ASC");
$statement->bind_result($id, $name, $utilities);
$statement->execute();
while ($statement->fetch()) {
$arr[] = [ "id" => $id, "name" => $name, "utilities" => $utilities];
}
$statement->close();
return $arr;
}
EDIT updated code based on accepted solution:
I added this to my db.php:
public function joinDevRoom()
{
$arr = array();
$statement = $this->conn->prepare("SELECT r.name,GROUP_CONCAT(u.device) FROM room r LEFT JOIN utilities u ON FIND_IN_SET(u.id,r.utilities)>0 GROUP BY r.id");
$statement->bind_result($id, $utilities);
$statement->execute();
while ($statement->fetch()) {
$arr[] = [ "id" => $id, "utilities" => $utilities];
}
$statement->close();
return $arr;
}
and this is my updated confroomreport.php:
<?php
require_once("db.php");
$arr = $conn->getConfRoomList();
$join = $conn->joinDevRoom();
?>
<table border='1'>
<tr>
<th>Room</th>
<th>Utilities</th>
</tr>
<?php for( $i=0; $i < count($arr); $i++) {
print_r ("<tr>
<td>".$arr[$i]['name']."</td>"); }
for( $u=0; $u < count($join); $u++) {
print_r ("<td>".$join[$u]['utilities']."</td>
</tr>"); } ?>
</table>
Try this
SELECT r.Name,GROUP_CONCAT(u.Device) FROM rooms r
LEFT JOIN utilities u ON FIND_IN_SET(u.id,r.Utilities)>0
GROUP BY r.ID

How to select and assign to a specific $key, a specific $value, among multiple choices?

I have a MySQL table with multiple columns, from which I need to select all of them of each record, and to create a specific $key=>$value from it.
for example
TABLE
ID | group_cat | group_sec | group_name | enabled | sent
-------------------------------------------------------------------------------------
1 | C | sct_a | Project_A | 1 | no
2 | C | sct_b | Project_B | 1 | no
3 | P | sct_c | Moderators | 1 | no
4 | C | sct_d | Ambassad | 1 | no
5 | P | sct_e | PMP | 0 | no
The MySQL query I need is "SELECT * FROM groups WHERE sent = 'no' "
By PHP is
PHP Code
$query = "SELECT * FROM `groups` WHERE `sent`= 'no' ";
$sth = $sql->prepare($query);
$sth->execute();
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
foreach($row as $key => $value) { $$key = $value; }
...
...
...
}
Here my question:
I need that the $key is from the column 'group_sec' and the related $value is from the column 'group_name'. So that the couple $$key=>$value can return this result (for instance)
echo $sec_b;
returns: Project_B
Could you help me to get this done please?
Thank you in advance
This will do the job for you:
${$row['group_sec']} = $row['group_name'];
echo $sct_b;
Output:
Project_B
You would use this in your while loop (the foreach can probably be deleted):
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
${$row['group_sec']} = $row['group_name'];
...
// do something with $sct_b
...
}
Alternatively, if your column names might change, but the positions will stay the same, you can use
while($row = $sth->fetch(PDO::FETCH_NUM)) {
${$row[2]} = $row[3];
...
// do something with $sct_b
...
}
You can build an array based on key and value you prefer using $row['group_sec'] for key and $row['group_name'] eg:
$query = "SELECT * FROM `groups` WHERE `sent`= 'no' ";
$sth = $sql->prepare($query);
$sth->execute();
while($row = $sth->fetch(PDO::FETCH_ASSOC)) {
$myArray[$row['group_sec']] = $row['group_name'];
}
and you can see the result
foreach($myArray as $key => $value){
echo $key . ' - ' . $value . '<br>';
}
$sql = "SELECT * FROM groups WHERE sent= 'no'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
$list=[];
while($row = $result->fetch_assoc()) {
$list{$row['group_sec']} = $row['group_name'];
}
}

Remove Duplicates in while loop PHP

I'm trying to remove duplicate results from my SQL query using PHP.
table categories:
id | name
1 | sony
2 | nintendo
table subcategories:
id | name | category_id
1 | playstation | 1
2 | playstation2 | 1
3 | wii | 2
table video_games
id | name | subcategories
1 | grand theft auto | 1,2
2 | super mario | 3
My PHP code:
$query = $database->query('SELECT id FROM subcategories WHERE category_id = "'.$_GET['id'].'"');
while($return = $query->fetch()) {
$subcategories = $return['id'];
$request = '%'.$subcategories.'%';
$game_query = $database->prepare('SELECT * FROM video_games WHERE subcategories LIKE :request');
$game_query->bindValue('request', $request);
$game_query->execute();
if($game_query->rowCount() > 0) {
while($game_return = $game_query->fetch()) {
echo $game_return['name'];
}
}
}
My code works but I have duplicate video games when there have multi subcategories.
I tried using SELECT DISTINCT * FROM video_games WHERE subcategories LIKE :request but same problem.
Any idea to remove duplicate results using SQL or PHP ?
MySql is able to solve this problem by its own means.
Use 'DISTINCT' and 'FIND_IN_SET'.
Like this:
"SELECT DISTINCT
vg.id,
vg.name,
vg.subcategories
FROM
video_games vg
WHERE
FIND_IN_SET( (SELECT id FROM subcategories WHERE category_id='".$_GET['id'])."' , vg.subcategories ) > 0 "
and also you can use array_unique at first save video game names in an array and next remove duplicate value.
.
.
.
your code
.
.
$game_query->execute();
if($game_query->rowCount() > 0) {
$fetch =array_unique($game_query->fetch());
foreach ($fetch as $key => $value){
echo $value;
}
}
test
<pre>
<?php
$arr=array("name"=>"1","name2"=>"2","name1"=>"2","name3"=>"3","name4"=>"1","name5"=>"2","name6"=>"3","name7"=>"22");
print_r($arr);
$fetch =array_unique($arr);
print_r($fetch);
foreach ($fetch as $key => $value)
echo $key."=>".$value."<br>";
?>
</pre>
You can save video game names in an array, and print it afterwards. For example:
$games = array();
$query = $database->query('SELECT id FROM subcategories WHERE category_id = "'.$_GET['id'].'"');
while($return = $query->fetch()) {
$subcategories = $return['id'];
$request = '%'.$subcategories.'%';
$game_query = $database->prepare('SELECT * FROM video_games WHERE subcategories LIKE :request');
$game_query->bindValue('request', $request);
$game_query->execute();
if($game_query->rowCount() > 0) {
while($game_return = $game_query->fetch()) {
if (!in_array($game_return['name'], $games)) {
$games[] = $game_return['name'];
}
}
}
}
//now print the games
foreach ($games as $game) {
echo $game;
}
EDIT If you want more than just 'name', you can expand $games array with $key => $value combination. For example:
. . .
while($game_return = $game_query->fetch()) {
foreach ($games as $game) {
if ($game['name'] === $game_return['name']]) {
continue 2;
}
}
$games[] = array(
'name' => $game_return['name'],
'price' => $game_return['price'],
)
}
And afterwards print it like:
foreach ($games as $game) {
echo $game['name'];
echo $game['price'];
}

How can I echo the variables properly using foreach?

I have 2 foreach loop which gets colors and sizes. I also have for loop which generate the material number. I'm trying to achieve distribute the variables well for example I have 2 colors with 3 sizes.
This is the desired output
Material# | Color | Size
1001 | Blue | Small
2001 | Blue | Medium
3001 | Blue | Large
4001 | Green | Small
5001 | Green | Medium
6001 | Green | Large
Here's my code:
//insert material number
for($x = 1; $x <= $matnumbersize; $x++ )
{
$matnummm= str_pad($x, 3, '0', STR_PAD_LEFT);
$materialnumber = $newgennumber.$matnummm;
$matnumberr[] = $materialnumber; //materialnumber
$stmt = $db->prepare("INSERT INTO materialnumber(productID,stylecodeID,genericnumberID,materialnumber) VALUES(:pid,:scode,:gcode,:matnum)");
$stmt->execute(array(':pid' => $productID, ':scode' => $styleID, ':gcode' => $gennumID, ':matnum' => $materialnumber));
}
print_r($matnumberr);
$statement = $db->prepare("SELECT * FROM productcolor a, color b where a.productID = :pid and a.colorID = b.colorID ");
$statement->execute(array(':pid' => "$productID"));
foreach ($statement->fetchAll() as $row)
{
$colorcode = $row['colorCode'];
$statement = $db->prepare("SELECT * FROM productsizes where productID = :pid ");
$statement->execute(array(':pid' => "$productID"));
foreach ($statement->fetchAll() as $row)
{
$sizeCde = $row['sizeName'];
echo $colorcode.$sizeCde.'<br/>';
}
}
I tried my best but I cant think a fix of it. Thank you!
I fixed it and manage to make it shorter so here's my code
$y = 1;
$statement = $db->prepare("SELECT * FROM productcolor a, color b where a.productID = :pid and a.colorID = b.colorID ");
$statement->execute(array(':pid' => "$productID"));
foreach ($statement->fetchAll() as $row)
{
$colorcode = $row['colorCode'];
$statement = $db->prepare("SELECT * FROM productsizes where productID = :pid ");
$statement->execute(array(':pid' => "$productID"));
foreach ($statement->fetchAll() as $row)
{
$sizeCde = $row['sizeName'];
echo $colorcode.$sizeCde.'<br/>';
$yy= str_pad($y, 3, '0', STR_PAD_LEFT);
$newmaterialnum = $newgennumber.$yy;
$stmt = $db->prepare("INSERT INTO materialnumber(productID,stylecodeID,genericnumberID,materialnumber,color,size)
VALUES(:pid,:scode,:gcode,:matnum,:color,:size)");
$stmt->execute(array(':pid' => $productID, ':scode' => $styleID, ':gcode' => $gennumID, ':matnum' => $newmaterialnum,
':color' => $colorcode, ':size' => $sizeCde));
$y++;
}
}

Save MySQL results in 2D array - php

I'm trying to fetch the result of a query to my database. I have no problems doing so when the resultset is just 1 row, but when it's multiple rows I only get the first one.
Here is my db:
-----keys-------------------
| id | key_nbr | date |
----------------------------
| 42 | abc123 | xxxx |
| 49 | 789xyz | wxyz |
----------------------------
My function:
function get_key_info($mysqli) {
if (isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'])) {
$user_id = $_SESSION['user_id'];
if ($stmt = $mysqli->query("SELECT id, key_nbr, date FROM keys WHERE id=$user_id")){
$row = $stmt->fetch_array(MYSQLI_ASSOC);
return $row;
}
}
return null;
}
Output when doing print_r($row); is only the first row:
Array ( [id] => 42 [key_nbr] => abc123 [date] => xxxx) How to make it print all rows?
You have to check for total number of rows before fetching the data, if it's not zero then execute the loop and fetch all records.
function get_key_info($mysqli) {
if (isset($_SESSION['user_id'], $_SESSION['username'], $_SESSION['login_string'])) {
$user_id = $_SESSION['user_id'];
if ($stmt = $mysqli->query("SELECT id, key_nbr, date FROM keys WHERE id=$user_id")){
if($stmt->num_rows != 0) {
$row = array();
while($r = $stmt->fetch_array(MYSQLI_ASSOC)) {
$row[] = $r;
}
return $row;
}
}
}
return null;
}

Categories