PHP Build a Basic PHP Website (2018) Listing and Sorting Inventory Items Random Fun with Arrays

I don't understand something!

Why use it like this?

foreach ($random as $id){
              echo get_item_html($id,$catalog[$id]);
           }

//Instead of just like before, can someone explain why cause she doesn't.

foreach ($random as $id => $item){
          echo get_item_html($id,$item);
        }

7 Answers

Hi Michael,

Array elements have both a key and a value.

You would use the first foreach loop when you are only interested in the value of an element. The second version of the foreach loop is used when you need both the key and the value.

Here's the code that you're asking about:

$random = array_rand($catalog, 4);
foreach($random as $id) {
    echo get_item_html($id, $catalog[$id]);
}

$random is the result of calling the array_rand function with our array of catalog items. The array_rand function will pick out 4 random keys from the catalog array and then return a new array with those keys as values.

That's the important part. The keys picked out from the catalog array become values in the returned array.

The value of each element in $random is one of our item id's like 101 for example.

This is why the foreach loop is used like that. We're only interested in the value of each element in $random.

Let me know if you need further explanation.

I thought of one more thing, it might be helpful to you to do a var_dump to see what the $random array looks like.

You can place var_dump($random); right before the foreach loop. It's going to mess up the layout so take it back out when you're done.

This is my result: (you'll likely have different numbers)

array(4) { [0]=> int(102) [1]=> int(202) [2]=> int(203) [3]=> int(304) }

As you can see, the array_rand function picked out the keys 102, 202, 203, and 304 from the catalog. These are then added to a new array as values.

The keys of this new array are 0, 1, 2, 3 and the values are 102, 202, 203, 304

The keys aren't important for us. It's the values that we need. This is why we use the first version of the foreach loop. We're not interested in the keys of this array.

Leigh Maher
Leigh Maher
20,340 Points

Thanks Jason. Very clear answer here, and great follow ups below, especially where you've used actual value examples : )

Sam Donald
Sam Donald
36,301 Points

Ok

Yes, I get it now thanks.

I don't know how many other people out there get mixed up with this one. But since the code targets the $catalog array key to source the array item value(s), and every conversation refers to that portion of an array as the key. Do you think maybe it would be more clear to use the variable $key instead of $id for this coding example?

Not just for teaching here, where people are just learning PHP. But in the real world too. I'm thinking for clarity, like good commenting improves code flow/handover within a team. Creating a variable $key when storing an array key value just makes the code that little bit clearer. I think.

John Lukacs
John Lukacs
25,194 Points

Im am getting this error message in the browser Parse error: syntax error, unexpected 'foreach' (T_FOREACH) in /home/treehouse/workspace/index.php on line 17

$random = array_rand($catalog, 4)
  foreach($random as $id) {
 echo get_item_html($id, $catalog[$id]); 
}

my code look identical to her;s why won't my code display? Any idea's

try to post it with ``` so we can see the code

You're missing a semicolon at the end of $random = array_rand($catalog, 4)

John Lukacs
John Lukacs
25,194 Points

Open up the launch workspace from the Build a basic php site chapter 2 Displaying Catogorys lession and view it in browser and you will see the teachers code does not work. It does not display this is so bad. Why Am I paying for this

Sam Donald
Sam Donald
36,301 Points

Why does php store the targeted keys as $id?

Everywhere else, in both documentation and application we reference these as keys. So why not $key?

See code comments.

$random = array_rand($catalog,4);
shuffle($random);
    // This $id is local and could be called anything (i.e. $item, $result etc...)
    foreach($random as $id) {
        // The first $id is the local. The second $id is used to target 4 keys of the $catalog array. 
        echo get_item_html($id,$catalog[$id]); 
    }

Hi Sam,

I'm not really sure what you're asking. As you mention in your first comment, $id could be anything. Since it's holding our item id's it makes sense to give it a descriptive name like $id to indicate what it's storing. $key is just a generic name for an arrays keys.

And technically, in this foreach loop $id isn't storing the keys of the $random array but rather the values.

In your second comment you seem to be making a distinction between the 2 $id's, but they are the same thing.

Sam Donald
Sam Donald
36,301 Points

The point I was trying to make was as you pointed out, $key is the generic name for an arrays keys. So for the sake of clarity and readability why note keep the convention in place and use the $key handle?

I know loop $id isn't storing the keys, but it is targeting the keys to pull the associated array item values. Isn't it?

As for my second comment, I though there was a difference between the two $id's. I thought it was saying run through the $random array four times ( which is actually the $catalog array ), store the results in a new variable called $id. Then echo out that $id with the value of $catalog's $id (read: the value associated to the key of the returned array item).

And that's why I though it made more sense for the 2nd $id to be $key, as we are targeting the keys of $catalog to then return the associated array item values from $catalog.

Do you get what I'm trying to say? Even if I'm wrong about the $id's, do you get me?

To clarify what you mean, are you suggesting that in the 3 places you see $id that it should be changed to $key?

Alex Forseth
Alex Forseth
8,016 Points

Wait so is $id the number 101,102,103 ect or is it the "genre", "category" keys? Confusing.

Hi Alex,

Yes, $id is storing the numbers 101, 102, etc...

Alex Forseth
Alex Forseth
8,016 Points

But I thought foreach loops could only access associate arrays?

A foreach loop is for accessing any array in php.

We might think of an array with integer keys as an indexed or numerical array and one using strings for keys as an associative array but PHP doesn't really make a distinction between these two. In fact, you can have an array with mixed keys where you have both integers and strings for keys.

A foreach loop can access any of those arrays along with multi-dimensional ones.

In general, any array in PHP is made up of key/value pairs. Sometimes when you create an array, you will have explicit key/value pairs. Other times, you will only specify the values and PHP will automatically generate integer keys for you.

Let me know if there is still something you're confused by.

Sam Donald
Sam Donald
36,301 Points

No.

The way I've interpreted it the 1st and 2nd $id's where representative of a local variable built to hold the returned value from the array.

But I though the 3rd $id was used to target or reference the key value of the array item in the $catalog array. So for that reason I thought it made more sense to maintain to key naming convention there.

So by my method it would be:

$random = array_rand($catalog,4);
shuffle($random);
    foreach($random as $id) { 
        echo get_item_html($id,$catalog[$key]); 
    }

I misunderstood then. In that case, the code won't work out because $key is an undefined variable. Nowhere in the code is $key assigned a value. You can change the variable name but all 3 places that you see $id needs to be the same variable name. And $key would be a misleading variable name in this case.

It might help to work with an actual value one time through the loop to help get you thinking about this the right way.

Suppose that we wanted to get the html for item 102. This is how we would have to call the function:

get_item_html(102, $catalog[102]);

So we pass in the item id for the 1st argument and for the 2nd argument we access the $catalog array at index or key 102 to get back an array with all the info for "Clean Code".

If you haven't yet read my follow up comment to my answer then I recommend that you do.

I'll re-post the result of the var_dump on the $random array.

array(4) { [0]=> int(102) [1]=> int(202) [2]=> int(203) [3]=> int(304) }

From that we know that the first time through the loop, the $id variable is going to store 102. This is why the $id variable needs to be in both arguments. We need to put that 102 in for the first argument and we need to use the 102 as an index into the catalog array for the second argument.

// When $id is 102
// this
get_item_html($id, $catalog[$id]);
// becomes
get_item_html(102, $catalog[102]);

Does that make more sense?