Hudzilla.org - the homepage of Paul Hudson
Contents > Introducing PHP > How PHP is written Wish List | Report Bug | About Me ]

2.6.13     Loops within loops

This is NOT the latest copy of this book; click here for the latest version.

You can stack loops up as you see fit simply by having one loop inside the body of another, like this:

for ($i = 1; $i < 3; $i = $i + 1) {
    for (
$j = 1; $j < 4; $j = $j + 1) {
        for (
$k = 1; $k < 3; $k = $k + 1) {
            print
"I: $i, J: $j, K: $k\n";
        }
    }
}

The output of that script is:

I: 1, J: 1, K: 1
I: 1, J: 1, K: 2
I: 1, J: 2, K: 1
I: 1, J: 2, K: 2
I: 2, J: 1, K: 1
I: 2, J: 1, K: 2
I: 2, J: 2, K: 1
I: 2, J: 2, K: 2

In this situation, using break is a little more complicated, as it only exits the closest loop. For example:

for ($i = 1; $i < 3; $i = $i + 1) {
    for (
$j = 1; $j < 4; $j = $j + 1) {
        for (
$k = 1; $k < 3; $k = $k + 1) {
            print
"I: $i, J: $j, K: $k\n";
            break;
        }
    }
}

This time the script will print out the following:

I: 1, J: 1, K: 1
I: 1, J: 2, K: 1
I: 2, J: 1, K: 1
I: 2, J: 2, K: 1

As you can see, the $k loop only loops once because of the break call. However, the other loops execute several times. You can exercise even more control by specifying a number after break, such as "break 2" to break out of two loops or switch/case statements. For example:

for ($i = 1; $i < 3; $i = $i + 1) {
    for (
$j = 1; $j < 4; $j = $j + 1) {
        for (
$k = 1; $k < 3; $k = $k + 1) {
            print
"I: $i, J: $j, K: $k\n";
            break
2;
        }
    }
}

That outputs the following:

I: 1, J: 1, K: 1
I: 2, J: 1, K: 1

This time the loop only executes twice, because the $k loop calls "break 2", which breaks out of the $k loop and out of the $j loop, so only the $i loop will go around again. This could even be "break 3", meaning break out of all three loops and continue normally.

It is important to remember that "break" works both on loops and switch/case statements. For example:

for ($i = 1; $i < 3; $i = $i + 1) {
    for (
$j = 1; $j < 4; $j = $j + 1) {
        for (
$k = 1; $k < 3; $k = $k + 1) {
            switch(
$k) {
                case
1:
                    print
"I: $i, J: $j, K: $k\n";
                    break
2;
                case
2:
                    print
"I: $i, J: $j, K: $k\n";
                    break
3;
            }
        }
    }
}

The "break 2" line will break out of the switch/case block and also out of the $k loop, whereas the "break 3" line will break out of those two and also the $j loop. To break out of the loops entirely from within the switch/case statement, "break 4" is required.





<< 2.6.12 Special loop keywords   2.6.14 Mixed-mode processing >>
Table of Contents
Want to see this stuff in print? PHP in a Nutshell takes the core topics covered here, adds in thousands of edits from the editorial team and myself, and combines them to make an unbeatable reference for PHP programmers at all levels.



My latest book has hundreds more tips on how to use PHP, Apache, and MySQL, plus Perl, Python, shell scripts, performance tuning, and more!



Top-right shadow
 
Bottom-left shadow Bottom shadow

Comments from other readers
Viren Beniwal - 30 Aug 2008

The Page is Quite Good For a New Learner To The PHP.

ajekigbe1@yahoo.com - 30 Aug 2008

I can now enjoy this site better for I have bought a copy of the latest edition-2006 copyright and I have noticed that there is no this typo error of $j<4.

$j<3.

Thank you.

A PHP User - 30 Aug 2008

What came to mind when I read this was a 3-tiered water fountain in reverse.lol.not overflowing is represented as 1. overflowing and not in j's case is represented by 2. and 3 is overflow for j.
Before the bottom tier can overflow into a waterfall the top waterfall must overflow. But before that happens, it must full up with water(i=1,j=1,k=1), then it full up with water), and starts to overflow into the next tier(i=1,j=1,k=2), which fulls up(i=1,j=2,k=1).K=1 is a flaw in my metaphore, so lets say the fountain has a whole in and empties into j.so now k has to full up again(i=1,j=2,k=2) but this empties into j again(i=1,j=3,k=1) then bla bla bla, (i=1,j=3,k=2) and so on and so forth. this is the association that came to mind. hope it helps you

A PHP User - 30 Aug 2008

I have a basic question -- does the action of the child for loop control the parent, or the other way around? Once the "k" loop completes, does this 'activate' the start of the "j" loop, or is the "k" loop start dependent on the completion of the "j" loop?

ajekigbe1@yahoo.com - 30 Aug 2008

MATT,
Thank you. Thank you very much. Thank you very very much. I am a 53yrs old man from a developing country and trying to learn a Web programming language.

This excellent book on PHP with its concomitant opportunity provided on the internet has made me to accept PHP as the language to stick to.

Now, the concept of nested loops which I have been struggling to understand for decades has simplly been solved by Matt. I cannot thank you enough.

However, I think j<3 is not false, for j<4. Esteemed regards.

A PHP User - 30 Aug 2008

This page is well explained. There is an error with the value of $j. It should be 3 not 4. With that correction, everything should run fine and i found this page very useful and easy to understand for a php newbie like me.

Skyblaze - 30 Aug 2008

yes, the second "for" statement is supposed to has the condition like this: "$j < 3" and not "$j < 4". So a typo error.

SemperFi - 30 Aug 2008

So far I am engrossed in this text. I have bought many programming books, never fully comprehending them. However this resource really motivates me that I may be able to do some programming.

Thanks!

TxtEdMacs - 30 Aug 2008

The code referred to in my previous post outputs the following:

I: 1, J: 1, K: 1
I: 1, J: 1, K: 2
I: 1, J: 2, K: 1
I: 1, J: 2, K: 2
I: 1, J: 3, K: 1
I: 1, J: 3, K: 2
I: 2, J: 1, K: 1
I: 2, J: 1, K: 2
I: 2, J: 2, K: 1
I: 2, J: 2, K: 2
I: 2, J: 3, K: 1
I: 2, J: 3, K: 2

which differs from the text. OK, I used the the cli package for version 4:
PHP 4.3.10-15 (cli) (built: May 9 2005 08:54:56)
Copyright (c) 1997-2004 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies

However, there is no difference between this version execution and version 5. On Debian, I still am unable to reload php5-cli, but I am hoping for its early return.

TxtEdMacs - 30 Aug 2008

Matt - you struck the heart of the problem I have with this code:

you said:
Next, $k is set to 3, which means "$k < 3" is false
...
Now $j = 3, so "$j < 3" is false and we go up to the "i" loop

but look at the code:

for ($i = 1; $i < 3; $i = $i + 1) {
for ($j = 1; $j < 4; $j = $j + 1) {
for ($k = 1; $k < 3; $k = $k + 1) {
print "I: $i, J: $j, K: $k\n";

<b>Note:</b> the condition on j is "$j < 4", which is True! Hence, it should have cycled through this loop once more and then into the k loop.

I just could not get my command line option running with my current Linux distribution. Can anyone just run it to check? The results just appear incorrect to me!

Thanks Matt - 30 Aug 2008

Matt, your comment below was most excellent for me to understand this page. I wanted to let you know I personally appreciate your explanation.

Matt - 30 Aug 2008

Let me see if I can explain it to the last person who posted...

Ok

for ($i = 1; $i < 3; $i = $i + 1) {
for ($j = 1; $j < 4; $j = $j + 1) {
for ($k = 1; $k < 3; $k = $k + 1) {
print "I: $i, J: $j, K: $k\n";
}
}
}

First, $i is set to 1
Then, $j is set to 1
Then, $k is set to 1 and everything is "print"ed
Next, (still in the "k" loop) $k is set to 2 (and print)
Next, $k is set to 3, which means "$k < 3" is false
Now the loop exits so we go up a level in the nest
The "j" loop has not completed so $j is set to 2
Now the entire "k" loop starts again...
...
"Then, $k is set to 1 and everything is "print"ed
Next, (still in the "k" loop) $k is set to 2 (and print)
Next, $k is set to 3, which means "$k < 3" is false
Now the loop exits so we go up a level in the nest"
...
Now $j = 3, so "$j < 3" is false and we go up to the "i" loop

This all continues, tell me if that makes sense.
Remember, in nested loops like this, once the bottom-most loop ("k") completes, it will start over for its parent loop ("j")

I hope this helps, I just get it because of TI-83+ basic.

A PHP User - 30 Aug 2008

I'm a true newbie, but have been gliding along easily up to here. (This is by far the most thorough and comprehensible help I have found on the web so far.) But this page has me stumped...

I cannot figure out how the output for the first example is logically created. Why is line 3 of the output not:

I: 1, J: 2, K: 2 instead of:

I: 1, J: 2, K: 1, as shown?

How does the counter on the K get set back? This page simply baffles me without some explanation for the execution order of nested loops.

But thanks for everything so far. Its a great help.

A PHP User - 30 Aug 2008

Is there a typo for j?
It never reached 3

A PHP User - 30 Aug 2008

"break 2" to break out of two loops

ooooooooooooooooooooooo i thought it had to do with the swtich statement variable or the variable the for loop intializes, neat. i see what you mean by control.

A PHP User - 30 Aug 2008

I didn't find it very helpful either but i did find refuge @ a site that used the example of an odometer. it quickly gave the understanding how the parent for loop controls its child. im still a little confused with the breaks but im going to keep playing with the code. great book so far!

A PHP User - 30 Aug 2008

As a beginner I've found following this page quite hard,as said above,maybe a revision of this page?

A PHP User - 30 Aug 2008

There are mistakes in your first and second output for the J value. J should reach and print value 3.

Or maybe it's typo error for the loop. It supposed to be

for ($i = 1; $i < 3; $i = $i + 1) {
for ($j = 1; $j < 3; $j = $j + 1) {
for ($k = 1; $k < 3; $k = $k + 1) {
print "I: $i, J: $j, K: $k\n";
}
}
}

A PHP User - 30 Aug 2008

To the contrary, I thought it was great. I've used PHP for a while but I'm learning a lot here.

A PHP User - 30 Aug 2008

Your explanation of nested loops doesn't have to be intimidating. I suggest a revision of this page.



Add comment
Please note that by posting a comment here you are committing it to the public domain. This is important so that others can make use of your code themselves, and also so that I can incorporate helpful notes directly into the main text. Comments are limited to 2000 characters in length.

If you are reporting an error in the content, please tell me directly.

Your name/email address:
Your comment:
 
Now, in order to verify that you're a real person, please answer this simple question: what is two plus ten?
The answer is:
(please write in
numbers, eg 19)


Top-right shadow
 
Bottom-left shadow Bottom shadow