Groups of Data: Looping Through Arrays in PHP

One of the most common things to do with an array is to consider each element in the array individually and process it in some way. This may involve incorporating it into a row of an HTML table or adding its value to a running total.

The easiest way to iterate through each element of an array is with foreach(). The foreach() construct lets you run a code block once for each element in an array. Example 4-8 uses foreach() to print an HTML table containing each element in an array.

Example 4-8. Looping with foreach()

$meal = array(‘breakfast’ => ‘Walnut Bun’,

‘lunch’ => ‘Cashew Nuts and White Mushrooms’,

‘snack’ => ‘Dried Mulberries’,

‘dinner’ => ‘Eggplant with Chili Sauce’);

print “<table>\n”;

foreach ($meal as $key => $value) {

print “<tr><td>$key</td><td>$value</td></tr>\n”;

}

print ‘</table>’;

Example 4-8 prints:

<table>

<tr><td>breakfast</td><td>Walnut Bun</td></tr>

<tr><td>lunch</td><td>Cashew Nuts and White Mushrooms</td></tr>

<tr><td>snack</td><td>Dried Mulberries</td></tr>

<tr><td>dinner</td><td>Eggplant with Chili Sauce</td></tr>

</table>

For each element in $meal, foreach() copies the key of the element into $key and the value into $value. Then, it runs the code inside the curly braces. In Example 4-8, the code prints $key and $value with some HTML to make a table row. You can use whatever variable names you want for the key and value inside the code block. If the variable names were in use before the foreach(), though, they’re overwritten with values from the array.

When you’re using foreach() to print out data in an HTML table, often you want to apply alternating CSS classes to each table row. This is easy to do when you store the alternating class names in a separate array. Then, switch a variable between 0 and 1 each time through the foreach() to print the appropriate class name. Example 4-9 alternates between the two class names in its $row_styles array.

Example 4-9. Alternating table row classes

$row_styles = array(‘even’,’odd’);

$style_index = 0;

$meal = array(‘breakfast’ => ‘Walnut Bun’,

‘lunch’ => ‘Cashew Nuts and White Mushrooms’,

‘snack’ => ‘Dried Mulberries’,

‘dinner’ => ‘Eggplant with Chili Sauce’);

print “<table>\n”;

foreach ($meal as $key => $value) {

print ‘<tr class=”‘ . $row_styles[$style_index] . ‘”>’;

print “<td>$key</td><td>$value</td></tr>\n”;

// This switches $style_index between 0 and 1

$style_index = 1 – $style_index;

}

print ‘</table>’;

Example 4-9 prints:

<table>

<tr class=”even”><td>breakfast</td><td>Walnut Bun</td></tr>

<tr class=”odd”><td>lunch</td><td>Cashew Nuts and White Mushrooms</td></tr>

<tr class=”even”><td>snack</td><td>Dried Mulberries</td></tr>

<tr class=”odd”><td>dinner</td><td>Eggplant with Chili Sauce</td></tr>

</table>

Inside the foreach() code block, changing the values of loop variables like $key and $value doesn’t affect the elements in the actual array. If you want to change the array element values, use the $key variable as an index into the array. Example 4-10 uses this technique to double each element in the array.

Example 4-10. Modifying an array with foreach()

$meals = array(‘Walnut Bun’ => 1,

‘Cashew Nuts and White Mushrooms’ => 4.95,

‘Dried Mulberries’ => 3.00,

‘Eggplant with Chili Sauce’ => 6.50);

foreach ($meals as $dish => $price) {

// $price = $price * 2 does NOT work

$meals[$dish] = $meals[$dish] * 2;

}

// Iterate over the array again and print the changed values

foreach ($meals as $dish => $price) {

printf(“The new price of %s is \$%.2f.\n”,$dish,$price);

}

Example 4-10 prints:

The new price of Walnut Bun is $2.00.

The new price of Cashew Nuts and White Mushrooms is $9.90.

The new price of Dried Mulberries is $6.00.

The new price of Eggplant with Chili Sauce is $13.00.

There’s a more concise form of foreach() for use with numeric arrays, shown in Example 4-11.

Example 4-11. Using foreach() with numeric arrays

$dinner = array(‘Sweet Corn and Asparagus’,

  ‘Lemon Chicken’,

  ‘Braised Bamboo Fungus’);

foreach ($dinner as $dish) {

print “You can eat: $dish\n”;

}

Example 4-11 prints:

You can eat: Sweet Corn and Asparagus

You can eat: Lemon Chicken

You can eat: Braised Bamboo Fungus

With this form of foreach(), just specify one variable name after as, and each ele­ment value is copied into that variable inside the code block. However, you can’t access element keys inside the code block.

To keep track of your position in the array with foreach(), you have to use a separate variable that you increment each time the foreach() code block runs. With for(), you get the position explicitly in your loop variable. The foreach() loop gives you the value of each array element, but the for() loop gives you the position of each array element. There’s no loop structure that gives you both at once.

So, if you want to know what element you’re on as you’re iterating through a numeric array, use for() instead of foreach(). Your for() loop should depend on a loop vari­able that starts at 0 and continues up to one less than the number of elements in the array. This is shown in Example 4-12.

Example 4-12. Iterating through a numeric array with for()

$dinner = array(‘Sweet Corn and Asparagus’,

  ‘Lemon Chicken’,

  ‘Braised Bamboo Fungus’);

for ($i = (, $num_dishes = count($dinner); $i < $num_dishes; $i++) {

print “Dish number $i is $dinner[$i]\n”;

}

Example 4-12 prints:

Dish number 0 is Sweet Corn and Asparagus

Dish number 1 is Lemon Chicken

Dish number 2 is Braised Bamboo Fungus

When iterating through an array with for(), you have a running counter available of which array element you’re on. Use this counter with the modulus operator (%) to alternate table row classes, as shown in Example 4-13.

Example 4-13. Alternating table row classes with for()

$row_stytes = array(‘even’,’odd’);

$dinner = array(‘Sweet Corn and Asparagus’,

  ‘Lemon Chicken’,

  ‘Braised Bamboo Fungus’);

print “<tabte>\n”;

for ($i = (, $num_dishes = count($dinner); $i < $num_dishes; $i++) {

print ‘<tr ctass=”‘ . $row_stytes[$i % ] . ‘”>’;

print “<td>Etement $i</td><td>$dinner[$i]</td></tr>\n”;

}

print ‘</tabte>’;

Example 4-13 computes the correct table row class with $i % 2. This value alternates between 0 and 1 as $i alternates between even and odd. There’s no need to use a sepa­rate variable, such as $style_index, as in Example 4-9, to hold the appropriate row class name. Example 4-13 prints:

<table>

<tr class=”even”><td>Element 0</td><td>Sweet Corn and Asparagus</td></tr>

<tr class=”odd”><td>Element 1</td><td>Lemon Chicken</td></tr>

<tr class=”even”><td>Element 2</td><td>Braised Bamboo Fungus</td></tr>

</table>

When you iterate through an array using foreach(), the elements are accessed in the order in which they were added to the array. The first element added is accessed first, the second element added is accessed next, and so on. If you have a numeric array whose elements were added in a different order than how their keys would usually be ordered, this could produce unexpected results. Example 4-14 doesn’t print array ele­ments in numeric or alphabetic order.

Example 4-14. Array element order and foreach()

$tetters[0] = ‘A’;

$tetters[1] = ‘B’;

$tetters[3] = ‘D’;

$tetters[2] = ‘C’;

foreach ($tetters as $tetter) {

print $tetter;

}

Example 4-14 prints:

ABDC

To guarantee that elements are accessed in numerical key order, use for() to iterate through the loop:

for ($i = (, $num_letters = count($tetters); $i < $num_letters; $i++) {

print $letters[$i];

}

This prints:

ABCD

If you’re looking for a specific element in an array, you don’t need to iterate through the entire array to find it. There are more efficient ways to locate a particular element. To check for an element with a certain key, use array_key_exists(), shown in Example 4-15. This function returns true if an element with the provided key exists in the provided array.

Example 4-15. Checking for an element with a particular key

$meals = array(‘Watnut Bun’ => 1,

‘Cashew Nuts and White Mushrooms’ => 4.95, ‘Dried Mulberries’ => 3.00,

‘Eggplant with Chili Sauce’ => 6.50,

‘Shrimp Puffs’ => 0); // Shrimp Puffs are free!

$books = array(“The Eater’s Guide to Chinese Characters”,

‘How to Cook and Eat in Chinese’);

// This is true

if (array_key_exists(‘Shrimp Puffs’,$meals)) {

print “Yes, we have Shrimp Puffs”;

}

// This is false

if (array_key_exists(‘Steak Sandwich’,$meals)) {

print “We have a Steak Sandwich”;

}

// This is true

if (array_key_exists( 1, $books)) {

print “Element 1 is How to Cook and Eat in Chinese”;

}

To check for an element with a particular value, use in_array(), as shown in Example 4-16.

Example 4-16. Checking for an element with a particular value

$meals = array(‘Walnut Bun’ => 1,

‘Cashew Nuts and White Mushrooms’ => 4.95,

‘Dried Mulberries’ => 3.00,

‘Eggplant with Chili Sauce’ => 6.50,

‘Shrimp Puffs’ => 0);

$books = array(“The Eater’s Guide to Chinese Characters”,

‘How to Cook and Eat in Chinese’);

// This is true: key Dried Mulberries has value 3.00

if (in_array( , $meals)) {

print ‘There is a $3 item.’;

}

// This is true

if (in_array(‘How to Cook and Eat in Chinese’, $books)) {

print “We have How to Cook and Eat in Chinese”;

}

// This is false: in_array() is case-sensitive

if (in_array(“the eater’s guide to chinese characters”, $books)) {

print “We have the Eater’s Guide to Chinese Characters.”;

}

The in_array() function returns true if it finds an element with the given value. It is case-sensitive when it compares strings. The array_search() function is similar to in_array(), but if it finds an element, it returns the element key instead of true. In Example 4-17, array_search() returns the name of the dish that costs $6.50.

Example 4-17. Finding an element with a particular value

$meals = array(‘Walnut Bun’ => 1,

‘Cashew Nuts and White Mushrooms’ => 4.95,

‘Dried Mulberries’ => 3.00,

‘Eggplant with Chili Sauce’ => 6.50,

‘Shrimp Puffs’ => 0);

$dish = array_search(5.50, $meals);

if ($dish) {

print $dish costs \$6.50″; 

}

Example 4-17 prints:

Eggplant with Chili Sauce costs $6.50

Source: Sklar David (2016), Learning PHP: A Gentle Introduction to the Web’s Most Popular Language, O’Reilly Media; 1st edition.

Leave a Reply

Your email address will not be published. Required fields are marked *