Why does this loop execute only once? - php

I found such php code :
$a = 5;
$i = 4;
for($i = &$a; $i < 10; ++$i);
echo "a=$a, i=$i";
I would expect this loop to be executed 4 times since $i becomes a reference to a$(right?). However loop is executed only once and outputs :
a=10, i=10
I can't figure outh why it works like this. Any ideas?

It works because the for statement is being processed like a single line statement as a result of the semicolon.
for($i = &$a; $i < 10; ++$i);
can also be seen as
for($i = &$a; $i < 10; ++$i) echo $i;
Without the curly brackets, the following line will be considered part of the for statement, your line being just a semicolon to indicate the end of the line.
The proper code would look like this.
$a = 5;
for($i = $a; $i < 10; ++$i) echo "a=$a, i=$i";

Related

Explain Alternative PHP For Loop Syntax: for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i, $i++);

This example has been given as an alternative example (example 4 to be precise) for writing for loops on PHP.net.
for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i, $i++);
I understand for loops, I just don’t understand why the variable, $j, is declared in this version of writing a for loop that prints the numbers 1 to 10.
FYI: Removing the variable from the for loop makes absolutely no difference to the result.
I think that it's just here for illustrate the fact that you can use multiple statement with commas.
It's useless here but show an example of the syntax for :
[...] Each of the expressions can be empty or contain multiple expressions separated by commas. In expr2, all expressions separated by a comma are evaluated but the result is taken from the last part. [...]
While it doesn't seem to be necessary in this example. It appears that $j is storing the summation of the iterations:
1+2+3+4+5+6+7+8+9+10 = 55
Which can be useful in some situations. So that would mean this style of looping is for the equivalent of doing several operations on each iteration, such as getting the summation, average, largest value, etc. The point of the example is that you can apply several statements separated by commas.
Explanation
for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i, $i++);
for loops takes three part separated by semicolon (;).
Initialize
Compare and test
Increment or Decrements.
Here $i=1, $j=0 is initialization.
$i<=10; is compare and test
$j += $i, print $i, $i++ is increment or decrements part
Now in your increment or decrements part you have three task.
1. is increment $j with last $i
2. print $i
3. increment $i by 1
So in your program $j is not useful. Because it is not taking part of
either print or compare and test.
So the loop is just very simple if you remove $j from every where and write it as
for ($i = 1; $i <= 10; $i++){
print $i;
}
But that $j variable could be used after the loop where from you have taken this code block.
LIKE
for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i, $i++);
print $j;
We can remove $j and have the same result:
for ($i = 1; $i <= 10; print $i, $i++);

How to I increment a single element in an array?

I have the PHP code below:
<?php
$length = $_GET["length"];
$maxValue = $_GET["maxValue"];
$distribution = array();
for($j = 0; $j < $maxValue; $j++) {
$distribution[j] = 5;
}
$x = 0;
$x++;
for($j = 0; $j < $maxValue; $j++) {
echo $distribution[j] , " ";
}
echo $x;
?>
$x starts as 0 and is incremented by 1. However, just below $x is incremented, I am also incrementing the first element of the "distribution" array - $distribution[0]. And it's not working. It worked fine when I was initializing the elements (set them to 5).
Any ideas on why it might now be working? I am probably referencing the array element wrong. But this seems inconsistent.
When you say $distribution[j] -> php doesn't understand the j as a variable - but rather as an undefined constant
It looks like you are trying to say $distribution[$j] - which is partially -why your increments aren't working - -
The other reason would be that you aren't ever calling $distribution[$j]++ --- so there is no incrementation happening...

Display random files from a directory?

how to display random files from a directory? The code below only shows random 1 file, output should be 10 files.
<?php
$path = "/files";
$files = scandir($path);
shuffle($files);
for($i = 0; ($i < count($files)) && (!is_file($files[$i])); $i++);
echo $files[$i];
?>
for($i = 0; ($i < count($files)) && (!is_file($files[$i])); $i++);
^
Putting the semicolon there terminates the for loop statement, hence it doesn't actually do anything, and just loops until the condition is false. Remove the semi-colon to fix.
As a clearer example, take the following code:
for($i = 0; $i < 5; $i++);
echo $i;
This will loop five times, as the for loop body statement is blank (due to the statement terminator, the semicolon). Because indentation doesn't matter in PHP, the echo $i will only echo once at the end of the loop, when $i == 5. You can view it better as the following:
for($i = 0; $i < 5; $i++)
;
echo $i;

Adding or condition in for loop

How can I add or in for loop check?
for example:
for ($i=1; ($i <= $untilPoint) or ($i <= $points); $i++){
.. code ...
}
Exactly what you typed is valid PHP. For example, this program:
<?
$untilPoint = 3;
$points = 5;
for ($i=1; ($i <= $untilPoint) or ($i <= $points); $i++){
echo("$i\n");
}
?>
prints this:
1
2
3
4
5
(tested in PHP 5.2.17, run from the Bash prompt).
That said, I wonder if maybe you really need and rather than or? If $i is an index into an array of points, where $points is the number of points and $untilPoint is an arbitrary cutoff, then you want and, not or.
This is how it should be done, probably it runs slightly faster.
You can separate with , see http://php.net/manual/en/control-structures.for.php for more information
<?
$untilPoint = 3;
$points = 5;
for ($i=1; $i <= $untilPoint, $i <= $points; $i++){
echo($i , "\n");
}
?>

Pre-incrementation vs. post-incrementation

How are they different? Here's what I'm thinking, but I'm not sure....
If you use pre-incrementation, for example in a for loop with ++j, then you are basically saying: "Make a copy of the value of j for use in the loop, then increment j, then go through the statements in the loop with the copy of j." If you are using post-incrementation in the same loop j++, then you are basically saying: "Make a copy of the value of j for use in the loop, then go through the statements in the loop with the copy of j, then increment j."
The reason I'm unsure is because I've created a for loop that multiplies the value of j by 10 and then outputs the result for j=1 through j=12, using both post- and pre-incrementation. The human readable output is exactly the same with post- and pre-incrementation. I'm thinking, 'How are the outputs exactly the same if there isn't some kind of copy operation involved?'
So, I'm guessing the difference between pre- and post-incrementation truly becomes important, in php, when I use references (which act as pointers in php) rather than names for return values? This would be because copies of references aren't made, so pre-incrementation would be: "Increment j, then go through the statements in the loop with the changed value of j, then increment j again...," whereas post-incremetation would look like: "Use the value of j for the statements in the loop, then change the value of j, then go through the loop with the new value of j..."
Pre- or post-incrementing do not magically delay things until later. It's simply inline shorthand.
// pre-increment
$var = 5;
print(++$var); // increments first, then passes value (now 6) to print()
// post-increment
$var = 5;
print($var++); // passes value (still 5) to print(), then increments
Now let's look at a loop.
for ($i = 0; $i < 9; $i++) {
print($i);
}
The last part of the loop declaration (the $i++) is simply the statement to execute after each time through the loop. It "passes" the value to nowhere, then increments it. $i isn't used anywhere at that time. Later when the next statement is executed (print($i);), the value of $i has already increased.
// add 1, then do nothing with $i
for ($i = 0; $i < 9; ++$i) {}
// do nothing with $i, then add 1
for ($i = 0; $i < 9; $i++) {}
Whichever way you do it, $i will be the same within the loop.
If it helps, you can think of them as small routines that kind of do this:
// ++$i
{
$i = $i + 1;
return $i;
}
// $i++
{
return $i;
$i = $i + 1;
}
As I reread your question, I think the confusion is more with how the loop works than how increment operators work. Keeping in mind that the increment is a straightforward, all-at-once operation, here's how third expression in the loop works.
// here's a basic loop
for ($i = 0; $i < 9; $i++) {
// do loop stuff
print($i);
}
// this is exactly what happens
for ($i = 0; $i < 9; ) {
// do loop stuff
print($i);
$i++;
}
Just because that last line can be put in the loop declaration doesn't give it any special powers. There are no references or anything used behind the scenes. The same $i variable is seen both inside and outside the loop. Every statement inside or outside the loop directly looks up the value of $i when necessary. That's it. No funny business.
When doing $x++, you are post-incrementing... This means that the incrementation will only occur after the statement has been evaluated.
So, given the following code:
$x = 10; $y = 0; $z = 5;
$y = $z * $x++;
PHP does this:
$x = 10; $y = 0; $z = 5;
$y = $z * $x++;
// Ignore Post-Increment, Evalutate
$y = $z * $x;
$y = 5 * 10;
// Now Increment x - POST-INCREMENT
$x = $x + 1;
$x = 10 + 1;
$x = 11;
// Continue evaluating statement
$y = 5 * 10;
$y = 50;
When doing ++$x, you are pre-incrementing... This means that the incrementation will occur before the statement is evaluated:
$x = 10; $y = 0; $z = 5;
$y = $z * ++$x;
// Do Pre-Increment
$x = $x + 1;
$x = 10 + 1;
$x = 11;
// Evaluate
$y = $z * $x;
$y = 5 * 11;
$y = 55;
In the case of a for loop in PHP, PHP evaluates a for loop as follows:
for($i = 0; $i < 30; $i++) {
doSomething();
}
// Is evaluated EXACTLY as such by PHP
$i = 0;
while($i < 30) {
doSomething();
$i++;
}
The first expression ($i = 0) is evaluated (executed) once unconditionally at the beginning of the loop.
In the beginning of each iteration, $i < 30 is evaluated. If it evaluates to TRUE, the loop continues and the nested statement(s) are executed. If it evaluates to FALSE, the execution of the loop ends.
At the end of each iteration, $i++ is evaluated (executed) as an independent expression.
Therefore, post-incrementing or pre-incrementing a variable as the third expression in the loop doesn't have an effect on the behavior of it. In this simple case, both expressions will behave exactly the same.
However, in a complex loop such as the following:
for($i = $j = 0; $i < 30; $i += ++$j) {
$j = getResult($j);
}
Post-incrementing or pre-incrementing $j directly affects the value of $i according to the examples above. In this case, you need to choose exactly what you want to do.
$i = 0;
echo $i++;
echo $i;
$j=0;
echo ++$j;
echo $j;
Pre increment display incremented value. But Post increment display value then increment. About code will output 01 and 11

Categories