I am writing PHP code with a for-loop:
for($i=1;$i<=count($ArrayData);$i++){
//some code that changes the size of $ArrayData
}
Does the program check the loop condition ($i<=count($ArrayData)) every time or only once?
Thanks
Every time.
From the PHP manual:
for (expr1; expr2; expr3)
...
In the beginning of each iteration, expr2 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.
This can also be verified by using a snippet like:
<?php
function compare($i)
{
echo 'called'.PHP_EOL;
return $i < 5;
}
for($i = 0; compare($i); $i++) {}
which should print:
called
called
called
called
called
called
(Note that the 6th time compare is called, it returns FALSE, but still prints called.)
[ Demo ]
It is checking it every iteration, for example:
for($i=1;$i<count($ArrayData);$i++){
$ArrayData[]=1;
}
will last until memory is exhausted, it will yield for example:
Fatal error: Allowed memory size of 536870912 bytes exhausted
To change it to checking only once once, use this:
for($i=1,$c =count($ArrayData); $i<=$c;$i++){
$ArrayData[]=1;
}
As $i is incremented in every iteration. Condition is also checked in every iteration against new value of $i as long as loop is running.
Related
I have this code.
$add = (function () {
$counter = 0;
return function () use(&$counter) {return $counter += 1;};
})();
echo $add(); //1
echo $add(); //2
echo $add(); //3
Expected Output:
111
Original Output:
123
Inside the function $counter=0 is assigned by 0 so the &$counter should be 0.
So when i called it second time it sees $counter=0 and so that &$counter will be 0, Isn't it?
Why it is incrementing?
It does not call $counter=0 for the second time. You call it just once when initiating the first function. When you call $add(), you call every time the second function (that is in your return statement) which just uses the modified value of $counter that you passed by reference. If you would add echo $counter; after the $counter = 0; you will see that.
What do you mean by "sees"? The first time you execute $add(), the inner counter is counted up. As you used a reference pointer (through adding the ampersand in use(&$counter)) to the original $counter, this is also manipulated, so after executing this once, the counter variable no longer contains a zero.
When you remove that ampersand, the innermost function uses a fresh counter each and every time, such that your expected output is met
Because you pass a reference to the function the initial $counter = 0; value is also increased each time you add 1 to it using $counter += 1; that's why your result is "123".
To get "111" you need to pass a variable to a function $counter, not a reference.
Usually, before entering a foreach loop, we would call reset or end to find the first or last item in an array. But, this doesn't play well with generators, especially those which are memory intensive. The simple solution would be to use iterator_to_array. Again, not the ideal solution. It requires copying the whole output to memory and a second iteration.
Checking for the first item could be done by setting a simple bool before the loop. But what about the last item? With access to the class which supplies the generator, I can implement the \Countable interface to get the number of expected iterations. That only works IF I have access, sometimes it may be third party and cannot be modified.
How can I detect the last iteration of a generator loop without having to loop through beforehand?
In the while loop you can manually check a generator state by the additional call of valid() method:
function g() {
for ($i = 0; $i < 10; ++$i) {
yield $i;
}
}
$g = g();
while ($g->valid()) {
echo "Value ", $g->current();
$g->next();
echo $g->valid() ? " is not last\n" : " is last\n";
}
I have the following PHP code that gives a "Fatal error: Maximum execution time of 30 seconds exceeded" message whenever it runs. If I remove the "if()" statement inside the second for loop the code runs without any problems. I cannot figure out why the "if()" statement would cause this error.
for ($i=1;$i<=$nParam;$i++){
for($j=0;$j<=$nParam-1;$j++){
if ($j=$i-1){
//do something
}
}
}
You are assigning a value, not comparing.
Use:
if ($j === $i-1){
You need to use == for your if statement. The way you have it at the moment is continuously resetting the value of $j to 0, which is making it loop for ever.
Change ($j=$i-1) it to
if ($j == $i-1){
//do something
}
== is for comparison
= is for assignment
hope this help.
You have a typo. You are using the assignment = operator instead of the comparison == operator:
if ($j=$i-1){ // <-- HERE
change it to
if ($j==$i-1){
I have a function which is returning some values. I want to put those values in an array after checking if the current value exists. I 've written the following code:
$return[0]=myexec_proc($varsearch,$get_input1);
if (isset($return[0])){
$return[1]=myexec_proc($varsearch,$return[0]);
}
if (isset($return[1])){
$return[2]=myexec_proc($varsearch,$return[1]);
}
if (isset($return[2])){
$return[3]=myexec_proc($varsearch,$return[2]);
}
if (isset($return[3])){
$return[4]=myexec_proc($varsearch,$return[3]);
}
which works as I want to but I need to do it with a for loop.
I've tried this:
$return=array();
for($i=0; $i=3; $i++){
if (isset($return[$i])){
$return[$i+1]=myexec_proc($varsearch,$return[$i]);
}}
but I get no data and after a while I get a php fatal error "Maximum execution time of 30 seconds exceeded".
Any tips on what I am doing wrong would be appreciated.
The second condition of your for loop is incorrect. You are assigning $i to 3 instead of checking it as a conditional.
It should be something like this:
for($i=0; $i<=3; $i++){
if (isset($return[$i])){
$return[$i+1]=myexec_proc($varsearch,$return[$i]);
}
}
For loops require a condition which they loop up until. Add a less than operator to make the for run correctly.
for ($i=0; $i<=3; $i++) {
if (isset($return[$i])) {
$return[$i+1]=myexec_proc($varsearch,$return[$i]);
}
}
I have been working with C# so this is quite strange for me:
while($variable=mysql_fetch_assoc)
{ $X=$variable['A'];
$Y=$variable['B'];
}
If it is like an ordinary loop, then X,Y will be reset with every loop, right?
I have not been able to look up in PHP manual how it works. I guess that in each loop it advances to next element of assoc.array. But what is this generally called in PHP? I am just not used to see '=' in loop condition.
Assignment in PHP is an expression that returns the value that was assigned. If a row was retrieved then the result will be non-false, which will allow the loop to continue.
mysql_fetch_assoc() (and its related functions) advance $result's internal pointer every time it gets called. So $variable will be assigned a new row array every time the while condition is checked. After the last row is returned, mysql_fetch_assoc() can't advance the internal pointer anymore, so the next attempt to call it will return false. Once $variable becomes false, the condition is no longer satisfied and the loop exits.
In PHP (also JavaScript et al), a condition is true as long as it doesn't evaluate to either zero, an empty string, NULL or false. It doesn't have to evaluate to a boolean value. That's why such a loop works.
EDIT:
If it is like an ordinary loop, then X,Y will be reset with every loop, right?
Yes, they'll be reassigned with the new values from each new row that is fetched.
Perhaps looking at the code like this would be useful:
while (($variable = mysql_fetch_assoc($result)) == true) {
// loops until the fetch function returns false (no more rows)
// $variable will have be an associative array containing the 'next' row from the recordset in $result
}
It's a shorthand way of doing this:
$variable = mysql_fetch_assoc();
while ($variable) {
// loop
$variable = mysql_fetch_assoc();
}
It means something like "until you can mysql_fetch_assoc() an element from the variable you pass to that function, then do the body of the while.
It returns an array if it can find an element, FALSE otherwise, so you can exit the loop.
It's just short form of this code:
$variable = mysql_fetch_assoc($res);
while($variable != FALSE) {
// do something
$variable = mysql_fetch_assoc($res);
}