New containing div after every 3 records

I would like to create a new containing <div> after 3 results, using PDO result loop.

For my self-study-project I have to made a product page with bootstrap and after every 3rd record I have to make a new row and show again 3 col-md-4's, etc, etc.

Now I have this as my code:

<div class="row">
    <?php
    while ($row = $stmt->fetch(PDO::FETCH_OBJ)) {
    ?>
        <div class="col-md-4">
            <div class="product">
                <div class="title"><?php echo $row->pname ?></div>
                <div class="img"><img
                    src="../product/img/<?php echo $row->pnumber ?>/<?php echo $row->pthumbnail ?>.jpg?$pop210x210$"/>
                </div>
                <div class="vijftien"></div>
                <div class="deliver">Levertijd: <strong><?php echo $row->pdelivertime ?></strong></div>
                <div class="vijf"></div>
                <div class="other"></div>
                <div class="row">
                    <div class="col-md-6">
                        <div class="price"><?php echo $row->pprice ?></div>
                    </div>
                    <div class="col-md-6">
                        <div class="order">
                            <button class="log_in" id="doLogin">Meer informatie</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    <?php } ?>
</div>

I have visited and studied other questions but I do not really get the idea of how they are doing it and how I can implement the correct method into my code.


Solution 1:

As tadman stated in the comment under your question. The best approach should use a modulus operator (%) with 3.

Place your separating condition at the start of each iteration. (Demo)

Like this:

$x=0;  // I prefer to increment starting from zero.
       // This way I can use the same method inside a foreach loop on
       // zero-indexed arrays, leveraging the keys, and omit the `++` line.
echo "<div class=\"row\">";
    foreach($rows as $row){
        if($x!=0 && $x%3==0){  // if not first iteration and iteration divided by 3 has no remainder...
            echo "</div>\n<div class='row'>";
        }
        echo "<div>$row</div>";
        ++$x;
    }
echo "</div>";

This will create:

<div class="row"><div>one</div><div>two</div><div>three</div></div>
<div class='row'><div>four</div><div>five</div><div>six</div></div>

Late Edit, here are a couple of other methods for similar situations which will provide the same result:

foreach(array_chunk($rows,3) as $a){
    echo "<div class=\"row\"><div>",implode('</div><div>',$a),"</div></div>\n";
}

or

foreach ($rows as $i=>$v){
    if($i%3==0){
        if($i!=0){
            echo "</div>\n";
        }
        echo "<div class=\"row\">";
    }
    echo "<div>$v</div>";
}
echo "</div>";

To clarify what NOT to do...

Sinan Ulker's answer will lead to an unwanted result depending on the size of your result array.

Here is a generalized example to expose the issue:

Using this input array to represent your pdo results:

$rows=["one","two","three","four","five","six"];

Sinan's condition at the end of each iteration:

$i=1;
echo "<div class=\"row\">";
    foreach($rows as $row){
        echo "<div>$row</div>";
        if($i%3==0)echo "</div>\n<div class='row'>";  // 6%3==0 and that's not good here
        // 6%3==0 and will echo the close/open line after the content to create an empty, unwanted dom element
        $i++;
    }
echo "</div>\n\n";

Will create this:

<div class="row"><div>one</div><div>two</div><div>three</div></div>
<div class='row'><div>four</div><div>five</div><div>six</div></div>
<div class='row'></div>                          //<--- this extra element is not good