Why does for(;;) work? - php

I was looking through some code at work and found something I've not encountered before:
for (; ;)
{
// Some code here
break;
}
We call the function that contains this all the time, I only recently got in there to see how it works. Why does this work and is it documented somewhere?
It seems as though a while loop would have been more appropriate in this instance...

It's essentially the same as while(true). It doesn't have any initialisation, doesn't change anything between iterations, and in the absence of anything to make it false the condition is assumed to be true.

It's an infinite loop.
Normally you would have something like:
for ($i=0; $i<10; $i=$i+1)
But you can omit any of the parts.
These are all valid:
for ($i=0; ; $i=$i+1)
for (; $i<10; $i=$i+1)
for (; $i<10;)
However, if you omit the second part, there will be no condition for exiting the loop. This can be used if you do not know how many times you want to run the loop. You can use a break instruction to exit the loop in that case
for (;;)
{
// some code
if (some condition)
break;
}
Note that if you do not put a break the page will just get stuck and run indefinitely

The first blank statement is executed at the beginning.
The second blank expression (which determines whether you exit the loop or not) evaluates to TRUE implicitly:
http://php.net/manual/en/control-structures.for.php
The third blank statement executes after each iteration.
So any condition that kicks out of the loop will need to be in the loop itself.

Related

php continue skips the condition evaluation

In my simple code 'continue' skips the condition evaluation and jumps straight to beginning of loop body (the if line) causing infinite loop. I can see that's exactly what happens when debugging and resuming execution with breakpoint on loop condition (it doesn't break) or when using step over. Probably just me being tired but I'm clueless.
while ( ($line = _e(fgets($dump_file))) !== FALSE )
{
if ($line === '')
{
echo 'continue';
continue;
}
You should use the break keyword to stop a loop.
Continue will go to the beginning of the next loop iteration while skipping the rest of your loop.
More info :
http://php.net/manual/en/control-structures.break.php
http://php.net/manual/en/control-structures.continue.php
continue will always continue to the next iteration of the loop.
The loop is infinite because the value of $line never changes within the loop, so either the loop infinitely executes or never does at all depending on the initial value of $line.
break will break out of the loop
You're assigning the result of _e to $line in your while loop. I'm assuming you're getting _e from WordPress, which is documented here: http://codex.wordpress.org/Function_Reference/_e .
Return Values
(void)
This function does not return a value.
So, your loop basically says:
while (void !== False) {
continue;
}
Which, of course, continues forever.
Note that several answers have stated that the break statement should have been used. The code above is designed to abort the loop when the end of file (EOF) is hit, to which fgets returns False. Each time the loop is run, fgets reads the next line until it reaches the end of the file, at which point it returns False.
From php.net:
Returns a string of up to length - 1 bytes read from the file pointed to by handle. If there is no more data to read in the file pointer, then FALSE is returned.
The problem here isn't that a break statement is needed, because the while condition will be false when fgets returns False. The issue is that _e returns void which !== False and therefore the loop continues indefinitely.
Quick solution is to remove the _e in the while statement and apply it to the string later in your code block if necessary.
OK so here's what happened. Problem with the infinite loop was indeed due to my _e function not accounting for it's argument being FALSE value and always returning a string so the while loop condition would always evaluate to TRUE as suggested by Ryan Vincent and geis.
However that does not explain why my debugger would not break on the condition. Turns out that this problem is not related. The debugger it self is acting out and now refusing to break on all kinds of random breakpoints for no good reason.
Marking geis's answer as solution for all the effort.

What does for(;;) do?

I have to maintain a code, and came up with this:
for (;;) {
//code
}
What would it do? I couldn't find documentation about it.
In a hunch I think it runs only once... but that would be useless...
it is an infinite loop, similar in function as:
while(true)
{
}
Your code sample is an infinite loop. To terminate, the omitted code (//code) must exit the loop or the entire PHP script.
It's a for loop without initialization parameters, no breaking conditions and no increments/decrements/whatever on each iteration - think of it like for (nothing; nothing; nothing).
Unless you break it from the inside, it's going to run forever.
For embedded code it is the main loop that does all the other sub process in a super loop scheme.

"Continue" alternative that doesn't skip but repeats the loop

I'm using PHP's foreach(), Sometimes when the inner code doesn't do what i want, I'd like to re-try the same level instead of continuing to the next one.
Is that possible?
Example:
foreach($pics AS $pic){
if(!upload($pic)){
again; // something like this
}
}
No but you can put a while loop inside your loop, this has equivalent behaviour as what you desire above. However you should modify it to use a counter and stop after X many retries to prevent infinite looping.
foreach($pics AS $pic){
while(!upload($pic));
}
You will need to surround your if with another loop which loops a certain number of times (your maximum retry count), or until you manually break out of it when your code succeeds.
You could use a goto I suppose, but that is generally frowned upon, and would do the same thing as an inner loop anyway.
function dosomething() {
foreach($pics AS $pic){
if(!upload($pic)){
break;
}
}
$success = true;
}
$success=false;
while( !$success ) dosomething();
While this in theory should work.
I would say absolutely bad programming practice, as you have a good chance of a never ending loop.

What does while (true){ mean in PHP?

I've seen this code, and I've no idea what it means.
while(true){
echo "Hello world";
}
I know what a while loop is, but what does while(true) mean? How many times will it executed. Is this not an infinite loop?
Although is an infinite loop you can exit it using break. It is useful when waiting for something to happen but you don't exactly know the number of iteration that will get you there.
Yes, this is an infinite loop.
The explicit version would be
while (true == true)
This is indeed (as stated already) an infinite loop and usually contains code which ends itself by using a 'break' / 'exit' statement.
Lots of daemons use this way of having a PHP process continue working until some external situation has changed. (i.e. killing it by removing a .pid file / sending a HUP etc etc)
Please referes to the PHP documentation currently at: http://www.w3schools.com/php/php_looping.asp
The while loop executes a block of code as long as the specified condition is true.
while (expression) {
statement(s)
}
The while statement evaluates expression, which must return a boolean value. If the expression evaluates to true, the
while statement executes the statement(s) in the while block. The
while statement continues testing the expression and executing its
block until the expression evaluates to false.
As a consequence, the code:
while (true) {
statement(s)
}
will execute the statements indefinitely because "true" is a boolean expression that, as you can expect, is always true.
As already mentioned by #elzo-valugi, this loop can be interrupted using a break (or exit):
while (true) {
statement(s)
if (condition) {
break;
}
}
It is indeed an infinite loop.

Differences between a while loop and a for loop in PHP?

I'm reading an ebook on PHP right now, and the author noted that the difference between a while loop and a for loop is that the for loop will count how many times it runs.
So take this:
<?php
for ($i = 1; $i < 10; $i = $i + 1) {
print "Number $i\n";
}
?>
But wouldn't this be the same as
<?php
$i = 1;
while ($i < 10) {
$i = $i + 1;
print "Number $i\n";
}
?>
Or is there some other differences that he didn't point out? (Aside from using while loop for when you're unsure of how long the condition will remain true, such as selecting rows from a database)
I mean, if that's the only difference, can't I just not use the for loop and use the while loop instead?
"For" expresses your intentions more clearly
Functionally, your two examples are the same. But they express different intentions.
while means 'I don't know how long this condition will last, but as long as it does, do this thing.'
for means 'I have a specific number of repetitions for you to execute.'
You can use one when you mean the other, but it's harder to read the code.
Some other reasons why for is preferable here
It's more concise and puts all the information about the loop in one place
It makes $i a local variable for the loop
Don't forget foreach
Personally, the loop I use most often in PHP is foreach. If you find yourself doing things like this:
for ($i=0; $i < count($some_array); $i++){
echo $some_array[$i];
}
...then try this:
foreach ($some_array as $item){
echo $item;
}
Faster to type, easier to read.
Can you? Yes, certainly. But whether or not you should is an entirely different question.
The for loop is more readable in this scenario, and is definitely the convention you'll find used within virtually every language that has looping directives. If you use the while loop, people are going to wonder why you didn't use a for loop.
Functionally, a for loop is equivalent to a while loop; that is, each can be rewritten as the other with no change to the outcome or side effects. However, each has different connotations. A while loop runs while a condition holds; the condition is static, though circumstances change. A for loop runs over a sequence. The difference is important to programmers but not programs, just as choice of variables names are important to programmers even though they can be changed to produce functionally equivalent code. One loop construct will make more sense than the other, depending on the situation.
A for-loop
for (INIT; CONDITIONS; UPDATE) {
BODY
}
is basically the same as a while-loop structured like this:
INIT
while (CONDITIONS) {
BODY
UPDATE
}
While you could technically use one or the other, there are situations where while works better than for and vice-versa.
The Main Difference Between for() and While() is that we have to define the limit or count but in while() loop we don't define limit or count it works until reached the last item
FOR LOOP
Initialization may be either in loop statement or outside the loop.
It is normally used when the number of iterations is known.
Condition is a relational expression.
It is used when initialization and increment is simple.
for ( init ; condition ; iteration )
{ statement(s); }
WHILE LOOP
Initialization is always outside the loop.
It is normally used when the number of iterations is unknown.
Condition may be expression or non-zero value.
It is used for complex initialization.
while ( condition )
{ statement(s); }
It's a matter of taste, personal preference and readability. Sometimes a while loop works better logically. Sometimes, a for.
For my personal rule, if I don't need a variable initializer, then I use a while.
But a foreach loop is useful in its own way.
Plus, in the case of PHP's scoping, where all variables not inside of functions are global, it the variable will continue living after the loop no matter which loop control you use.

Categories