How is an array in a PHP foreach loop read?

22,926

Solution 1

foreach() is implemented using iterators - thus it only calls the function that returns an array once, and then uses the iterator which points to the existing result set to continue with each item.

Solution 2

I think testing it will surely answer that.

Here is my code:

function GetArray() {
    echo "I am called.\n";
    return array("One"=>1, "Two"=>2, "Three"=>3, "Four"=>4, "Five"=>5);
}

echo "Case #1\n";
$array = GetArray();
foreach ($array as $key => $val){
    // Do stuff while traversing array
    echo "    Inside the loop: $key => $val\n";
}
echo "\n";

echo "Case #2\n";
foreach (GetArray() as $key => $val) {
    // Do stuff while traversing array
    echo "    Inside the loop: $key => $val\n";
}
echo "\n";

and here is the result:

Case #1
I am called.
    Inside the loop: One => 1
    Inside the loop: Two => 2
    Inside the loop: Three => 3
    Inside the loop: Four => 4
    Inside the loop: Five => 5

Case #2
I am called.
    Inside the loop: One => 1
    Inside the loop: Two => 2
    Inside the loop: Three => 3
    Inside the loop: Four => 4
    Inside the loop: Five => 5

They both read call function once. So no different.

Solution 3

foreach makes a copy of the input array and works on that in each iteration. So you can use foreach (do_something_that_returns_an_array() as $key => $val) and it'll call do_something_that_returns_an_array() only once.

Solution 4

I would set up an example to see what happens. Something like...

function do_something_that_returns_an_array() {
    echo 'I have been called!'; 
    return array('i am an', 'array');
}

As you can see on CodePad, it is only being called once.

Solution 5

I've always assumed that do_something_that_returns_an_array() only runs once because, unlike in the for loop, there's no reason for it to run multiple times. The reason the for loop truth checker runs at the end of every iteration is to allow for very complicated checkers.

As a test, I did the following:

function get_array() {echo 5; return array(1,2,3,4,5);}
foreach(get_array() as $key => $value) {}

The script printed 5 once. Therefore, the function get_array() only evaluates once.

Share:
22,926
BoltClock
Author by

BoltClock

My pronouns are they/them. Learn more. Curious about my profile picture? Check out my Flash game on Newgrounds! I'm a software developer who relishes authoring HTML and CSS on the web and hacking C# on their self-built Windows PC. I adore Jesus and the colors green, purple and teal, and I often catch myself thinking in numbers and code on a whim. I was also a Microsoft MVP from 2017 through 2020. My areas of specialty are in web design — I've known HTML and CSS for more than a decade now! — and Windows app development with C# and XAML. Other languages I've worked with include (from most to least experience) PHP, SQL, ActionScript, Swift, Objective-C, Perl, Python, and Java. Roles on this site From the tags I participate in (below) as well as my bio (above), it's easy to tell that I'm interested in a number of languages and topics. However, you'll most often find me patrolling, curating and moderating the following tags: htmlcsscss-selectorsinternet-explorermicrosoft-edge As a moderator, I believe I am more efficient than ever with post revisions and other housekeeping duties, as I continue with my question-answering business. While I actively add fresh content to the site, I'm also helping out with cleaning and polishing our currently-existing posts. "Dust tends to settle", and all that jazz. Achievements Singapore's top user by reputation and first community moderator ♦ on Stack Overflow! 1st user to earn the bronze, silver and gold css-selectors badges! 4th user to earn the gold css badge! 9th user to earn the gold html badge! 45th user to earn the Legendary badge! 54th user to reach the 100,000-reputation milestone!

Updated on July 21, 2022

Comments

  • BoltClock
    BoltClock almost 2 years

    We have all heard of how in a for loop, we should do this:

    for ($i = 0, $count = count($array); $i < $c; ++$i)
    {
        // Do stuff while traversing array
    }
    

    instead of this:

    for ($i = 0; $i < count($array); ++$i)
    {
        // Do stuff while traversing array
    }
    

    for performance reasons (i.e. initializing $count would've called count() only once, instead of calling count() with every conditional check).

    Does it then also make a difference if, in a foreach loop, I do this:

    $array = do_something_that_returns_an_array();
    
    foreach ($array as $key => $val)
    {
        // Do stuff while traversing array
    }
    

    instead of this:

    foreach (do_something_that_returns_an_array() as $key => $val)
    {
        // Do stuff while traversing array
    }
    

    assuming circumstances allow me to use either? That is, does PHP call the function only once in both cases, or is it like for where the second case would call the function again and again?