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.
Related
I'm wondering if the $count++ way of incrementing a counter is okay to use in a conditional statement? Will the variable maintain it's new value?
$count = 0;
foreach ($things as $thing){
if($count++ == 1) continue;
...
}
$count++ is a post-increment. That means that it will increment after the evaluation.
++$count is a pre-increment. That means that it will increment before the evaluation.
http://www.php.net/manual/en/language.operators.increment.php
To answer your question, that is perfectly valid, just keep in check that your value will be 2 after the if has been done.
Yes, it will, but you want to pay attention to the difference between $count++(post-incrementation) and ++$count(pre-incrementation), or you might not get the results you expect.
For instance, the code snippet you wrote will "continue" on the second "$thing", but go through the loop on the first, because the value of $count won't be incremented until after its value is tested. If that's what you're going for, then right on, but it's one of those common "gotchas", so I thought I should mention it.
As far as I know second and third expressions are executed every time in a for loop.
I always took for granted performance wise second option is recommended, can anyone confirm this?
1) for($i=0;$i<=dosomething();$i++) [...]
2)
$max = dosomething();
for($i=0;$i<=$max;$i++) [...]
You shouldn't call a function inside of a loop definition because that function will be executed every iteration. When you only have a small loop the effect is negligible, however if you have a loop of hundreds or thousands of iterations you'll definitely notice.
But even if you only have a small loop, it's just bad practice. So in a word: don't.
Unless your dosomething() function returns different values and it can be done in a single shot, it's better to use the second method.
$options = array(1,2,3,4,5);
$element_count = count($options);
Functions like count() that returns same value in multiple calls can be saved in a one variable and use it in your for loop.
If you are very strict for performance, use ++$i instead of $i++
The second method is always going to preform better, especially if there is substantial work to be done in doSomething(). If you are only doing tens of loops, and doSomething() is just returning a local variable, then it won't make a noticeable difference.
Yes I confirm you can search benchmarks if you want.
Though I don't know if it's true if it's only a getter to an object
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.
I have a variable, for example $total1. It has a value from the database, for example 6.
Now I do an SQL query and it gets some numbers from tables. For example this:
$subtraction1=5, but it is in a while loop so the second time it could be $subtraction1=10 or something like that. Every time in the while loop the $subtraction_total variable would be $subtraction_total1+$subtraction1, because at the bottom of the page I would like to show the $total minus the $subtraction_total1.
But the first time in the while loop I must check if $subtraction_total already exists. I know to options to do that, but is there a shorter way?
Option 1 is to define the variable $subtraction_total1 before the while loop.
Option 2 is to do this:
(!isset($total_subtraction1)){$total_subtraction1=0;}$total_subtraction1=$total1-$subtraction1;
Now you think: well, just do option 1: define 1 variable, but it is for around 15 variables and I was just wondering if there is a shorter way;-)
Hope you understand me, my English is not very good;-)
Define and initialize all your variables before use. I think Option 1 follows logically from that.
Don't try to write code that is short, or fast or tricky. Write code that is easy to read and maintain.
I would definitely advocate defining the variable(s) before the loop. Repeatedly calling isset (or any other function) over and over inside a loop is wasteful if the same functionality can be achieved pre-loop.
If you're simply looking to define a large number of variables without having to explicitly declare each one before your loop you might try listdocs or programmatically create your variables in a loop.
$sub_total = 0;
while ($sub = mysql_get_row(...)) {
$sub_total += $sub;
}
This way you don't execute the same code again in every iteration (which is good practice and good performance wise), and it has the added advantage that if you have no result from mysql, $sub_total is defined with a default value.
I use often the function sizeof($var) on my web application, and I'd like to know if is better (in resources term) store this value in a new variable and use this one, or if it's better call/use every time that function; or maybe is indifferent :)
TLDR: it's better to set a variable, calling sizeof() only once. (IMO)
I ran some tests on the looping aspect of this small array:
$myArray = array("bill", "dave", "alex", "tom", "fred", "smith", "etc", "etc", "etc");
// A)
for($i=0; $i<10000; $i++) {
echo sizeof($myArray);
}
// B)
$sizeof = sizeof($myArray);
for($i=0; $i<10000; $i++) {
echo $sizeof;
}
With an array of 9 items:
A) took 0.0085 seconds
B) took 0.0049 seconds
With a array of 180 items:
A) took 0.0078 seconds
B) took 0.0043 seconds
With a array of 3600 items:
A) took 0.5-0.6 seconds
B) took 0.35-0.5 seconds
Although there isn't much of a difference, you can see that as the array grows, the difference becomes more and more. I think this has made me re-think my opinion, and say that from now on, I'll be setting the variable pre-loop.
Storing a PHP integer takes 68 bytes of memory. This is a small enough amount, that I think I'd rather worry about processing time than memory space.
In general, it is preferable to assign the result of a function you are likely to repeat to a variable.
In the example you suggested, the difference in processing code produced by this approach and the alternative (repeatedly calling the function) would be insignificant. However, where the function in question is more complex it would be better to avoid executing it repeatedly.
For example:
for($i=0; $i<10000; $i++) {
echo date('Y-m-d');
}
Executes in 0.225273 seconds on my server, while:
$date = date('Y-m-d');
for($i=0; $i<10000; $i++) {
echo $date;
}
executes in 0.134742 seconds. I know these snippets aren't quite equivalent, but you get the idea. Over many page loads by many users over many months or years, even a difference of this size can be significant. If we were to use some complex function, serious scalability issues could be introduced.
A main advantage of not assigning a return value to a variable is that you need one less line of code. In PHP, we can commonly do our assignment at the same time as invoking our function:
$sql = "SELECT...";
if(!$query = mysql_query($sql))...
...although this is sometimes discouraged for readability reasons.
In my view for the sake of consistency assigning return values to variables is broadly the better approach, even when performing simple functions.
If you are calling the function over and over, it is probably best to keep this info in a variable. That way the server doesn't have to keep processing the answer, it just looks it up. If the result is likely to change, however, it will be best to keep running the function.
Since you allocate a new variable, this will take a tiny bit more memory. But it might make your code a tiny bit more faster.
The troubles it bring, could be big. For example, if you include another file that applies the same trick, and both store the size in a var $sizeof, bad things might happen. Strange bugs, that happen when you don't expect it. Or you forget to add global $sizeof in your function.
There are so many possible bugs you introduce, for what? Since the speed gain is likely not measurable, I don't think it's worth it.
Unless you are calling this function a million times your "performance boost" will be negligible.
I do no think that it really matters. In a sense, you do not want to perform the same thing over and over again, but considering that it is sizeof(); unless it is a enormous array you should be fine either way.
I think, you should avoid constructs like:
for ($i = 0; $i < sizeof($array), $i += 1) {
// do stuff
}
For, sizeof will be executed every iteration, even though it is often not likely to change.
Whereas in constructs like this:
while(sizeof($array) > 0) {
if ($someCondition) {
$entry = array_pop($array);
}
}
You often have no choice but to calculate it every iteration.