Home » Php » Using function call in foreach loop

Using function call in foreach loop

Posted by: admin November 30, 2017 Leave a comment

Questions:

Are there any issues, with regards to efficiency, for using a function call in a foreach loop. For example:

foreach ($this->getValues() as $value) {
  //Do something with $value
}

versus

$values = $this->getValues();
foreach ($values as $value) {
  //Do something with $value
}

Essentially, is php clever enough to call $this->getValues() only once in the first example, or does it call it on each iteration. If it calls it on each iteration, then how does it keep track of which element its currently at,

Answers:

These are both essentially the same:

foreach ($this->getValues() as $value) {
 //
}

$values = $this->getValues();
foreach ($values as $value) {
  //
}

$this->getValues() will only run once, as it is not inside the loop itself. If you need to use the return value of getValues again later, go ahead and assign it to a variable so you don’t have to call the function again. If not, you don’t really need a variable.

Questions:
Answers:

There may be a difference, but it is going to be negligible for 99.9% of real-world cases. In either case, PHP will call your function/method only once. What happens internally when you use foreach is that PHP evaluates the iteratee (the part before the as) once, stores the result, and then loops over it, putting the current element into the local variable given after the as. If you write the iteratee to a local variable yourself, you are practically just duplicating PHP’s effort, so the first approach may carry an extra overhead, but it’s not going to be enough to worry about. I’d optimize for readability instead: if the function call is short and self-describing, inline it; if it’s complex or obscure, store it in a descriptive variable instead.

Note that the situation is different with typical for and while loops, which is probably where you got this notion from. For example, in the following code:

for ($number = 0; $number < $this->getNumberOfItems(); ++$number) {
    // do stuff...
}

…the getNumberOfItems() method gets called on every iteration. In this situation, it makes sense to precalculate it and store it in a local variable.