everyone. I saw a PHP while loop example today that I don't quite understand.
Example (Complete code)
// Open XML file
$fp=fopen("note.xml","r");
// Read data
while ($data=fread($fp,4096)) { // Line about which I have questions
xml_parse($parser,$data,feof($fp)) or
die (sprintf("XML Error: %s at line %d",
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
The expression $data=fread($fp,4096) inside the while loop parentheses doesn't seem to change at all. It is just ONE assignment statement. How does this loop end?
The function xml_parse($parser,$data,feof($fp)) may end when parsing is complete, but I don't see how it will affect the test condition for the while loop. I feel the parsing of the XML file would repeat indefinitely.
Also when there is assignment expression as a test condition for a loop, are we really just looking to see if the RIGHT side of the assignment yields TRUE or FALSE to determine whether to end the loop? I have doubt about this though because then it would produce an infinite loop for this example since $data, once assigned, will always return TRUE.
Thanks
It ends when the fread() function returns false, which does when it reaches the end of the file. You can confirm this in the PHP documentation for fread:
http://php.net/fread
As for your question about the evaluation of the assignment, in PHP when you evaluate an assignment it will return the final value of the variable (different to Javascript for instance, in which the assignment is indeed what becomes evaluated), so you're basically both assigning a value to a variable from a function and evaluating the result of that function (assigned to the variable) without any extra syntax.
Work
while(there is data to read) OR (!EOF)
break when reach (EOF==true) OR no data to read OR return false
* EOF (end of file)
As php manual says, the function fread returns the read string or FALSE on failure.
That means:
$data=fread($fp,4096)
In the above statement the value of $data is either the contents of your file note.xml or false.
As you may know, while loop will continue until the condition is false. This statement is false only when fread($fp,4096) function fails to read data from the file, when there is no data left to read.
Related
<?php
var_dump(preg_match('#((.*)*/)#i', 'a/aaaaaaaaaaaaaaa'));
//return int 1
var_dump(preg_match('#((.*)*/)#i', 'a/aaaaaaaaaaaaaaaa'));
//return boolean false
?>
Whereas the regular expression is the same, and what changes is only the text that is being evaluated.
On the first line of code returns true, the faster and the second returns false, and slower ... coming to crash if placed in loop
There is an explanation for this, or is BUG
Trying other compliladores the result is the same
In Chrome console for example, this expression put the high processor clock
/((.*)*\/)/.test('a/aaaaaaaaaaaaaaaaaaaaaaaa');
In Flex, again... the same problem
I make this question because I had a code that some input parameters work, and others do not .. then simplified expression for the simplest point to demonstrate the error and got this case I'm showing.
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.
Is there any way to test if writing to a file was successfully accomplished? I need a method to obtain the end of time of a writing operation. If so to trigger a callback function.
fwrite() returns the number of bytes written, or FALSE on error.
Check whether fwrite() returns false and you'll know that the write succeeded. Be careful to use the === comparison operator instead of the == operator when checking if the returned value is false.
You can use filemtime() to get the last modification time of a file.
the code I'm looking at does this...
while ($info=mysql_fetch_array($data_jurisdiction))
{
//some stuff
}
I'm wondering what does this while statement do? it has an assignment operator within it, so as long as $info gets assigned a value other than false, this code will execute?
[... S]o as long as $info gets assigned a value other than false, this code will execute?
Quite, yes. Even there is an assignment operator within that expression, the expression itself still stands for a value. In this case the result of the whole expression is equal to the assignment to $info. In other words: The expression is the same as $info or the expression has been assigned to $info - the last variant is perhaps the best description.
So now whenever $info equals to true, the code block inside while will be executed.
Keep in mind that the comparison is a loose comparison. So not only false but as well NULL or an empty array will stop the execution of the inner code-block.
For each record $info will be populated with the current row, until it reaches the end of the result set when it will be set to false (which should stop the while loop).
great answer from hakre. what is said is that
while ($info=mysql_fetch_array($data_jurisdiction))
will execute in the same way as this
while (mysql_fetch_array($data_jurisdiction)==true)
or even this
$info = mysql_fetch_array($data_jurisdiction);
if($info==true)
so keep in mind that if mysql_fetch_array($data_jurisdiction) returns anything that can be evaluated to false, the assignment won't work. some of those values are (and I know I will forget a few:
0
"0"
false
"false"
NULL
""
array() (not fully sure about this one)
as long as $info gets assigned a value other than false, this code will execute?
Yes.
it does loop and stops if $info is false
mysql_fetch_array(); clears row by row so there is new result alltimes
A while loop will execute the nested statement(s) repeatedly, as long as the while expression evaluates to true.
The expression in your example $info = mysql_fetch_object($data_jurisdiction) checks whether the $info, the assigned value from mysql_fetch_object() is equal to true, after type juggling.
It is important to understand two things here:
mysql_fetch_object() returns the next row of the result set until the end of the data set is reached, where it returns false. See the method documentation here.
All assigned values of variables which are not equal to 0, or null evaluate to true after type juggling.
From the manual:
The value of an assignment expression is the value assigned. That is, the value of "$a = 3" is 3.
Also from the manual about mysql_fetch_array:
Returns an array of strings that corresponds to the fetched row, or FALSE if there are no more rows.
Therefore, once there are no more rows, the assignment will turn into:
$info = false
Which will get evaluated as false in the while condition, causing the loop to terminate.
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.