Skip to content

PHP Tutorial Loops

Nested Loops

Lesson 96 of 369 2 min read By Deepak Paswan Updated Oct 5, 2026

A loop can contain another loop. The inner loop runs completely for every single round of the outer loop.

index.php
PHP
<?php
for ($row = 1; $row <= 3; $row++) {
    for ($col = 1; $col <= 3; $col++) {
        echo "($row,$col) ";
    }
    echo "\n";
}
Output
OUTPUT
(1,1) (1,2) (1,3)
(2,1) (2,2) (2,3)
(3,1) (3,2) (3,3)

The outer loop runs 3 times. Each time, the inner loop runs 3 times, so the inside code runs 9 times in total.

A multiplication table

index.php
PHP
<?php
for ($i = 1; $i <= 4; $i++) {
    for ($j = 1; $j <= 4; $j++) {
        echo str_pad($i * $j, 4, " ", STR_PAD_LEFT);
    }
    echo "\n";
}
Output
OUTPUT
   1   2   3   4
   2   4   6   8
   3   6   9  12
   4   8  12  16

A star pyramid

index.php
PHP
<?php
for ($i = 1; $i <= 4; $i++) {
    echo str_repeat(" ", 4 - $i) . str_repeat("*", $i * 2 - 1) . "\n";
}
Output
OUTPUT
   *
  ***
 *****
*******

Nested arrays

This is the most common real use.

index.php
PHP
<?php
$classes = [
    "Class A" => ["Mia", "Noah"],
    "Class B" => ["Olivia", "Pete", "Quinn"],
];

foreach ($classes as $className => $students) {
    echo $className . ":\n";

    foreach ($students as $student) {
        echo "  - $student\n";
    }
}
Output
OUTPUT
Class A:
  - Mia
  - Noah
Class B:
  - Olivia
  - Pete
  - Quinn

Build an HTML table

index.php
PHP
<?php
$rows = [["Pen", 10], ["Book", 250]];

echo "<table>";
foreach ($rows as $row) {
    echo "<tr>";
    foreach ($row as $cell) {
        echo "<td>$cell</td>";
    }
    echo "</tr>";
}
echo "</table>";
Output
OUTPUT
<table><tr><td>Pen</td><td>10</td></tr><tr><td>Book</td><td>250</td></tr></table>

Watch the cost

Nested loops multiply work. Two loops over 1,000 items run 1,000,000 times. For large data, try to avoid nesting, for example by looking items up in an array by key instead of searching with an inner loop. See Avoiding Repeated Work.

lightbulb
Use different counter names
Name loop variables for what they mean ($row, $col, $student). Using $i and $j everywhere makes nested loops hard to read.