Unable to repeat/cycle through code with PHP and MySQL - php

<?php
$query = "SELECT name FROM prodGroups";
$result = mysql_query($query);
$prodGroups = array();
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$prodGroups[] = $row['name'];
}
if (count($prodGroups) == 0 && (!isset($products))) // IF NO PRODUCT GROUPS EXIST
for ($j=1 ; $j<4 ; $j++)
{
echo "<li><a href='#'><span>Empty product group " . $j . "</span></a></li>";
}
else // FOR WHEN PRODUCT GROUPS DO EXIST
foreach ($prodGroups as $aGroup) // CYCLE THROUGH PRODUCT GROUPS
{
echo "<li class='submenu'><a href='#'><span>" . $aGroup . "</span></a>";
}
for ($k=0 ; $k<3 ; ++$k)
{
$query = "SELECT name FROM products WHERE prodGroup='$prodGroups[$k]'";
$result = mysql_query($query);
for ($j=0 ; $j<count($prodGroups) ; ++$j)
{
while ($row2 = mysql_fetch_array($result, MYSQL_ASSOC)) // PLACE PRODUCTS INTO AN ARRAY
{
$products[] = $row2['name'];
}
if (!isset($products)) // IF THERE ARE NO PRODUCTS INSIDE A PRODUCT GROUP
echo "<ul><li><a href='#'><span>No products</span></a></li></ul></li>";
else // FOR WHEN PRODUCT(S) DO EXIST INSIDE A PRODUCT GROUP
echo "<ul>";
if(isset($products))
foreach ($products as $item) // CYCLE THROUGH PRODUCTS
{
echo "<li><a href='#'><span>" . $item . "</span></a>";
}
echo "</ul>";
}
}
?>
For some reason, I can only get products to display on the last iterate of the loop, and not all of them. A variable is obviously being over written but I cannot identify which one nor can I over come it?
EDIT
Now I've incorporated appropriate indentation and curly braces, I'm experiencing issues where ALL products are now showing in only the last prodGroup rather than their relevant/appropriate ones

Use brackets in your loop, and for your own good, everywhere else.
for ($j=0 ; $j<count($prodGroups) ; ++$j)
$query = "SELECT name FROM products WHERE prodGroup='$prodGroups[$j]'";
$result = mysql_query($query); // <- this won't be included in your loop

Related

How to get id while in a loop in php

Wanted to get 2 values id and name but im confuse how get it, i wanted to show the id in the link. heres the sample code.
echo "<table width=\"100%\" border=\"1\" cellpadding=\"5\" cellspacing=\"2\" bordercolor=\"#FFFFFF\">";
$count = 1;
$id=$_GET['id'];
$col1 = $col2 = array();
$rowcount = round(mysqli_num_rows($nquery) / 2);
while($crow = mysqli_fetch_assoc($nquery)) {
if($count > $rowcount) $col2[] = $crow['title'];
else $col1[] = $crow['title'];
$count++;
}
$counter = 0; // Arrays start with 0
foreach($col1 as $crow) { // $col1 will always be >= $col2
$row2 = (isset($col2[$counter])) ? $col2[$counter] : "";
echo "<tr><td><a href='index.php?page=".$id."'>" . $crow . "</td><td>" . $row2 . "</td></tr>";
$counter++;
}
echo "</table>";
?>`
id wont show up on the link. Hope someone can help. Thanks
You're trying to get $id values from the query string (that's what the $_GET superglobal is) and not from the database.
If both elements (ID and name) are coming from the same database query, you may try something like this:
$crow = mysqli_fetch_assoc($nquery);
foreach ($crow as $row)
{
echo $row['id'].' is the ID and '.$row['title'].' is the title';
}
if you remain within the foreach loop, you can use $row['id'] and $row['title'] to build the table element and link you're trying to obtain.

For each loop add 1 in PHP

I have been trying to return a list of results from MySQL using PHP.
The basic query is simple and the output is multiple columns. I want to add a number so the array looks like this:
Club 1
Club 2
I have tried the below but it keeps breaking the script:
if (mysqli_num_rows($result) > 0) {
while($row = mysqli_fetch_assoc($result)) {
for($i=1; $i++){
$club = $row['club_name'];
echo '<p>' . $i . $club . '</p>';
}
}
}
I have then tried placing the for statement outside the while and inside it, changed it to foreach and used the format ($i=1; $i<100; $i++){} and it still doesn't work.
Sorry if this is an obvious one I've tried numerous different ways and it just isn't working for me.
Try creating a counter variable ($i) and incrementing it on every iteration of the while loop ($i++), like this:
if (mysqli_num_rows($result) > 0) {
$i = 1;
while($row = mysqli_fetch_assoc($result)) {
$club = $row['club_name'];
echo '<p>' . $i . $club . '</p>';
$i++;
}
}
Then, to change the format to match 1. Club Name, change
echo '<p>' . $i . $club . '</p>';
to
echo "<p>$i. $club</p>";
But, I'd personally recommend to use an <ol> instead and skip setting the counter altogether like this:
if (mysqli_num_rows($result) > 0) {
echo "<ol>";
while($row = mysqli_fetch_assoc($result)) {
$club = $row['club_name'];
echo "<li>$club</li>";
}
echo "</ol>";
}

Warp two row with a class after query

I want to warp every two row with a class. So I saw some guideline from here and googling and found foreach array_chunk to do this. And I tried as below which can't display any result. Without foreach its work well. Were is my wrong here please?
In the above picture that I want to do; my every two category warp with a class. And add a divider after each top category.
Here is my tried:
echo '<ul class="dropdown-menu dropdown-menu-large row">';
$sql = "SELECT id,name FROM main_cata ORDER BY id ASC";
$execute = $dbh->query("$sql");
$rowcount = $execute->num_rows ;
$row = $dbh->query($sql) ;
while ($row = $execute->fetch_assoc()) {
foreach (array_chunk($row, 2, true) as $array){
echo'<li class="col-sm-3">';
foreach($array as $rows){
echo '<ul><li class="dropdown-header">'.$rows->name.'</li>';
$sql2 = "SELECT id,name,page FROM catagory WHERE m_cata = '".$rows->id."' ORDER BY id ASC";
$execute2 = $dbh->query("$sql2");
$rowcount2 = $execute2->num_rows ;
$row = $dbh->query($sql) ;
while ($row = $execute2->fetch_assoc()) {
$cid = $row['id'];
$cname = $row['name'];
$page = $row['page'];
echo '<li>'.$cname.'</li>';
}
echo '<li class="divider"></li></ul>';
}
echo '</li>';
}
}
echo '</ul>';
while ($row = $execute->fetch_assoc()) {
fetch_assoc returns 1 row (id, name) from the query, then you are using the result and spliting in 2 (https://secure.php.net/manual/pt_BR/mysqli-result.fetch-assoc.php), What you can do is, make a counter instead of the array chunk that resets every time it reachs 2.
foreach (array_chunk($row, 2, true) as $array){
The content of $row is, for example, array('id' => 1, 'name' => 'Category 1').
foreach($array as $rows){
You are iterating again without needing to.
A simple version:
counter = 0;
echo "<ul>";
while (row = execute->fetch_assoc()) {
if (counter == 0) {
echo "init li";
}
echo "subinit li";
get subcategories
while (row2 = execute2->fetch_assoc()) {
print content
}
echo "subend li";
if (counter == 2) {
counter == 0;
echo "end li";
} else {
counter++;
echo "divider";
}
}
echo "</ul>";

PHP Array is carrying too many elements

<?php
$query = "SELECT name FROM prodGroups";
$result = mysql_query($query);
$prodGroups = array();
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$prodGroups[] = $row['name'];
}
if (count($prodGroups) == 0) // IF NO PRODUCT GROUPS EXIST
for ($j=1 ; $j<4 ; $j++)
{
echo "<li><a href='#'><span>Empty product group " . $j . "</span></a></li>";
}
else // FOR WHEN PRODUCT GROUPS DO EXIST
foreach ($prodGroups as $aGroup) // CYCLE THROUGH PRODUCT GROUPS
{
echo "<li class='submenu'><a href='#'><span>" . $aGroup . "</span></a>";
$query = "SELECT name FROM products WHERE prodGroup='$aGroup'";
$result = mysql_query($query);
for ($j=0 ; $j<count($prodGroups) ; ++$j)
{
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) // PLACE PRODUCTS INTO AN ARRAY
**{
$products[] = $row['name'];
}**
if (!isset($products)) // IF THERE ARE NO PRODUCTS INSIDE A PRODUCT GROUP
echo "<ul><li><a href='#'><span>No products</span></a></li></ul></li>";
else // FOR WHEN PRODUCT(S) DO EXIST INSIDE A PRODUCT GROUP
{
echo "<ul>";
if(isset($products))
foreach ($products as $item) // CYCLE THROUGH PRODUCTS
{
echo "<li><a href='#'><span>" . $item . "</span></a>";
}
echo "</ul></li>";
}
}
}
?>
Where $products[] = $row['name']; it is carrying ALL the elements, whereas I just want it to carry product names to where they match the prodGroup name? I've tried using unset() to delete array contents in the loop, however this only allows one element in the array per cycle.
Add $products = array();
immediately after:
foreach ($prodGroups as $aGroup) // CYCLE THROUGH PRODUCT GROUPS
{
I tried to rewrite your loop, fixing several issues, most of them minor. I commented my changes. See if this works for you.
foreach ($prodGroups as $aGroup) // CYCLE THROUGH PRODUCT GROUPS
{
echo "<li class='submenu'><a href='#'><span>" . $aGroup . "</span></a>";
$query = "SELECT name FROM products WHERE prodGroup='$aGroup'";
$result = mysql_query($query);
//for loop here has been taken out
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) // PLACE PRODUCTS INTO AN ARRAY
{
$products[] = $row['name'];
}
if (!isset($products)) // IF THERE ARE NO PRODUCTS INSIDE A PRODUCT GROUP
echo "<ul><li><a href='#'><span>No products</span></a></li></ul>";
else // FOR WHEN PRODUCT(S) DO EXIST INSIDE A PRODUCT GROUP
{
echo "<ul>";
//if(isset($products)) - You already checked this..
foreach ($products as $item) // CYCLE THROUGH PRODUCTS
{
echo "<li><a href='#'><span>" . $item . "</span></a></li>"; //Don't forget to close this li
}
echo "</ul>";
}
echo '</li>'; //close li here
unset($products); //unset $products for next loop iteration
}
Of course, please do not use the deprecated mysql extension. See comment by #FreshPrinceOfSO.
This should be a little neater for you to see what I meant by using mysql_num_rows()
<?php
$query = "SELECT name FROM prodGroups";
$result = mysql_query($query);
if( (!$result) || (mysql_num_rows($result) == 0) )// IF NO PRODUCT GROUPS EXIST
{
for ($j=1 ; $j<4 ; $j++)
{
echo "<li><a href='#'><span>Empty product group " . $j . "</span></a></li>";
}
}
else // FOR WHEN PRODUCT GROUPS DO EXIST
{
while($row = mysql_fetch_array($result, MYSQL_ASSOC)) // CYCLE THROUGH PRODUCT GROUPS
{
echo "<li class='submenu'><a href='#'><span>" . $row['name'] . "</span></a>";
$query2 = "SELECT name FROM products WHERE prodGroup='".mysql_real_escape_string($row['name'])."'";
$result2 = mysql_query($query2);
if( (!$result2) || (mysql_num_rows($result2)==0) )
{
echo "<ul><li><a href='#'><span>No products</span></a></li></ul>";
}
else
{
echo "<ul>";
while ($row2 = mysql_fetch_array($result2, MYSQL_ASSOC)) // PLACE PRODUCTS INTO AN ARRAY
{
echo "<li><a href='#'><span>" . $row2['name'] . "</span></a></li>";
}
echo "</ul>";
}
echo "</li>";
}
}
?>

Display php nested array results continuously in two column table

I have a nested array grouping three other arrays: $online, $busy and $offline, in order to display results in this exactly order.
$conteudo = array($online, $ocupado, $offline);
The desired result would be a table in two columns to display results in continuous flow like this:
online1 | online2
online3 | busy1
busy2 | offline1
offline2| offline3
offline4|
I've been trying lots of foreach loops and playing around changing the html tags, but the closest I can arrive of the desired result is this:
<table width='100%' cellpadding='5' border="1">
<?php
$i = 1; //contador de colunas
$max_colunas = 2; // numero de colunas
foreach ($conteudo as $row) {
echo "<tr>";
foreach ($row as $col) {
foreach ($col as $cell) {
if ($i == 1) {
echo "<td>" . $cell . "</td>";
} elseif ($i == $max_colunas){
echo "<td>" . $cell . "</td></tr>";
$i = 0;
} else {
echo "<td>" . $cell . "</td>";
}
$i++;
}
}
echo "</tr>";
}
This code will output a table like this:
onine1 | online2 |online3
busy1 | busy2 |
offline1|offline2 |offline3|offline4
I can't find out why it ignores completely $max_colunas, seems like it prints all the elements inside the array in row.
If I remove lines:
echo "<tr>";
echo "</tr>";
from beginning and end of foreach it will output all in a row like this:
onine1 | online2 |online3 | busy1 | busy2 |offline1|offline2 |offline3|offline4
Any suggestions to get the desired output format will be so appreciated.
Edited on 17/01:
This is how I'm getting the arrays from:
//group people
$online = array(); //group online
$ocupado = array(); //group ocupado
$offline = array(); //group offline
//select people to group
$atendentes = mysql_query("SELECT nome FROM atendentes ORDER BY nome") or die(mysql_error());
$atendentedb = array();
//put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
$atendentedb[] = array('nome' => $row["nome"], 'online' => false);
}
//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();
foreach ($names as $name):
//foreach ($atendentedb as $atendente):
for($i = 0; $i < count($atendentedb); $i++):
$att = strtolower($name->username);
if ($atendentedb[$i]['nome'] == $att):
$atendentedb[$i]['online'] = true;
break;
endif;
endfor;
endforeach;
//check each selected people
foreach ($atendentedb as $atendente) :
//save temporary data
$online_ = $atendente['online'];
$nome_ = $atendente['nome'];
//if selected people online
if ($online_) :
//take status to show
$status = mysql_query("SELECT status FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($status)):
$statusdb = $row["status"];
endwhile;
//verify and save deppending on status
switch ($statusdb):
//if online
case "disponivel":
$descricao = mysql_query("SELECT hp_online FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($descricao)):
$online[] = array('info'=>$row['hp_online']);
endwhile;
break;
//if busy
case "ocupado":
$descricao = mysql_query("SELECT hp_busy FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($descricao)):
$ocupado[] = array('info'=>$row['hp_busy']);
endwhile;
break;
endswitch;
//if offline
else:
$descricao = mysql_query("SELECT hp_offline, horario FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
while ($row = mysql_fetch_assoc($descricao)):
$offline[] = array('info'=>$row['hp_offline'], 'horario'=>$row['horario']);
endwhile;
endif;
endforeach;
EDITED
So after following help instructions from DaveRandom I got to this code, which is really a drop away from the right format, except for the "mysterious" behaviour with results coming from array $offline, that are displaying all in "block" (all cells in a row, or all cells in a column) while the other arrays are displaying perfectly(??).
//group people
$online = $ocupado = $offline = array();
//select people to group
$query = "SELECT nome, status, hp_online, hp_busy, hp_offline, horario
FROM atendentes
ORDER BY nome";
$atendentes = mysql_query($query) or die(mysql_error());
$atendentedb = array();
// put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
$atendentedb[strtolower($row['nome'])] = array_merge($row, array('online' => FALSE));
}
//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();
foreach ($names as $name) {
$uname = strtolower($name->username);
if (isset($atendentedb[$uname])) $atendentedb[$uname]['online'] = TRUE;
}
//check each selected people
foreach ($atendentedb as $name => $atendente) {
//if selected people online
if ($atendente['online']) {
//verify and save deppending on status
switch ($atendente['status']) {
//if online
case 'disponivel':
$atendentedb[$name]['info'] = $online[] = $atendente['hp_online'];
break;
//if busy
case 'ocupado':
$atendentedb[$name]['info'] = $ocupado[] = $atendente['hp_busy'];
break;
}
//if offline
} else {
$atendentedb[$name]['info'] = $offline[] = $atendente['hp_offline'];
$atendentedb[$name]['info'] = $offline[] = $atendente['horario'];
}
}
//*******Display Results
$conteudo = array_merge($online, $ocupado, $offline);
$max_colunas = 2; // numero de colunas
// Start the table
echo '<table width="100%" cellpadding="5" border="1">'."\n";
// Loop all the objects
for ($i = 0, $j = 0; isset($conteudo[$i]); $i++) {
if ($j == 0) {
// Output the beginning of a row
echo " <tr>\n";
}
// Always output a data cell
echo " <td>$conteudo[$i]</td>\n";
if (++$j >= $max_colunas) {
// Output the end of a row and reset the cell counter
echo " </tr>\n";
$j = 0;
}
}
if ($j) {
// We may end up with an incomplete row at the end, so pad it with empty cells
// and close the row
while ($j++ < $max_colunas) {
echo " <td></td>\n";
}
echo " </tr>\n";
}
// Close the table
echo "</table>";
I would say that the first thing to do here is to "flatten" the array - having the multiple dimensions makes this a lot more complicated than it needs to be. So rather than creating $conteudo like this:
$conteudo = array($online, $ocupado, $offline);
...do this instead:
$conteudo = array_merge($online, $ocupado, $offline);
Then you can do this:
$max_colunas = 2; // numero de colunas
// Start the table
echo '<table width="100%" cellpadding="5" border="1">'."\n";
// Loop all the objects
for ($i = 0, $j = 0; isset($conteudo[$i]); $i++) {
if ($j == 0) {
// Output the beginning of a row
echo " <tr>\n";
}
// Always output a data cell
echo " <td>$conteudo[$i]</td>\n";
if (++$j >= $max_colunas) {
// Output the end of a row and reset the cell counter
echo " </tr>\n";
$j = 0;
}
}
if ($j) {
// We may end up with an incomplete row at the end, so pad it with empty cells
// and close the row
while ($j++ < $max_colunas) {
echo " <td></td>\n";
}
echo " </tr>\n";
}
// Close the table
echo "</table>";
See it working
EDIT
Try this code for generating your arrays. Note that the structure of your output arrays has been altered to fit my code sample above - if you use this data anywhere else in you script, you will need to modify that code as well. I have modified this so that there is only one database query, which would seem to be all that is required. I have also modified it so that the $atendentedb holds all the user data, including the status and info keys, and all rows contain a horario key.
Because of the fact that your input arrays originally contained more data than the ones created by this code will, the code may need further modification - but try this out and see how you get on.
//group people
$online = $ocupado = $offline = array();
//select people to group
$query = "SELECT nome, status, hp_online, hp_busy, hp_offline, horario
FROM atendentes
ORDER BY nome";
$atendentes = mysql_query($query) or die(mysql_error());
$atendentedb = array();
// put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
$atendentedb[strtolower($row['nome'])] = array_merge($row, array('online' => FALSE));
}
//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();
foreach ($names as $name) {
$uname = strtolower($name->username);
if (isset($atendentedb[$uname])) $atendentedb[$uname]['online'] = TRUE;
}
//check each selected people
foreach ($atendentedb as $name => $atendente) {
//if selected people online
if ($atendente['online']) {
//verify and save deppending on status
switch ($atendente['status']) {
//if online
case 'disponivel':
$atendentedb[$name]['info'] = $online[] = $atendente['hp_online'];
break;
//if busy
case 'ocupado':
$atendentedb[$name]['info'] = $ocupado[] = $atendente['hp_busy'];
break;
}
//if offline
} else {
$atendentedb[$name]['info'] = $offline[] = $atendente['hp_offline'].' '.$atendente['horario'];
}
}
I think you should update counter inside
foreach ($col as $cell) { } so it will count elements of the inner arrays and also move decalration of <tr> there.
if (!is_int($i/2)) { print '<tr><td>' }

Categories