简体   繁体   中英

PHP double while loop, second loop not iterating more than once

so I'm working on a "product listing", and the idea is to have the name of the product and then a drop down list of colours derived from the database. The problem is I can only get the "colours" while loop to iterate the once, I get the first product name and the colours in the drop down menu the once but not subsequently, the help I'd like is, how can I change this code to make it do what I need, I've been trying for a week and I could really use some help.

    $product_query = mysql_query('SELECT * FROM products WHERE id > 0');
$colour_query = mysql_query('SELECT * FROM product_colours WHERE id > 0');


while ($get_product_rows = mysql_fetch_assoc($product_query)){
echo $get_product_rows['name'];
    echo "<br \>";

    if ($get_product_rows['has_colour'] == '1'){
        while ($get_colour_row = mysql_fetch_assoc($colour_query)){
            // Drop down box population goes here.


        }
    }
}

If anyone can help I would appreciate it. From Grant M.

The way mysql_fetch_assoc() works is that it has an internal pointer, and every time you run the method, you get the next item and the pointer is moved one time. If there was no pointer, how would the while loop otherwise ever terminate? It would just keep pulling out colours, over and over.

The way to resolve this is to reset the point in each iteration. This can be done using mysql_data_seek() .

$product_query = mysql_query('SELECT * FROM products WHERE id > 0');
$colour_query = mysql_query('SELECT * FROM product_colours WHERE id > 0');

while ($get_product_rows = mysql_fetch_assoc($product_query)) {
    echo $get_product_rows['name'];
    echo "<br />";

    if ($get_product_rows['has_colour'] == '1') {
        while ($get_colour_row = mysql_fetch_assoc($colour_query)) {
            // Drop down box population goes here. 
        }
    }
    mysql_data_seek($colour_query, 0);
}

@Kristian Antonsen is quite right - once you've read the rows once you are at 'the end' unless you rewind to the beginning of the result set.

Alternatively to the other answers posted, because the colours aren't dependent on the product - get them once and then reuse them in memory.

// get the colours once
$colour_query = mysql_query('SELECT * FROM product_colours WHERE id > 0');
$colours = array();
while ($get_colour_row = mysql_fetch_assoc($colour_query)) {
  array_push($colours, $get_colour_row['colour']);
}

// loop through each product
$product_query = mysql_query('SELECT * FROM products WHERE id > 0');
while ($get_product_rows = mysql_fetch_assoc($product_query)) {
    echo $get_product_rows['name'];
    echo "<br />\n";

    if ($get_product_rows['has_colour'] == '1'){
        foreach ($colours as $colour) {
            echo $colour . "<br />\n";
        }
    }
}

The problem is that the second time around, the pointer is already at the end of the record for $colour_query ; it will continue to return null because it doesn't know that the nested loop is complete.

You can solve this problem by resetting the pointer using mysql_data_seek :

$product_query = mysql_query('SELECT * FROM products WHERE id > 0');
$colour_query = mysql_query('SELECT * FROM product_colours WHERE id > 0');

while ($get_product_rows = mysql_fetch_assoc($product_query)) {
    echo $get_product_rows['name'];
    echo "<br />";

    if ($get_product_rows['has_colour'] == '1') {
        while ($get_colour_row = mysql_fetch_assoc($colour_query)) {
            // Drop down box population goes here.
        }

        // Reset the pointer:
        mysql_data_seek($colour_query, 0);
    }
}

Also, your <br \\> is wrong; it should be <br /> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM