Документация
HTML CSS PHP PERL другое

Iterating Over Elements in an Array

 
Previous
Table of Contents
Next

Iterating Over Elements in an Array

There are times when you will want to visit all the elements in an array, either to operate on them, print them, or use them in an operation. This section will show the four most common ways to visit every element. We will primarily use the first throughout this book, but we'll show the others to help you understand any code that uses them.

foreach Loops

foreach (array as [key =>] values)
  block

PHP provides a language construct designed specifically to iterate over all elements in an arraythe foreach loop. To use it, you specify the array over which you would like to iterate along with the name of a variable. The loop executes once for each value in the array, and the named variable is given a copy of the value of the current iteration. The loop runs until there are no more items to use.

<?php

  $drinks = array("Coffee", "Café au Lait", "Mocha", "Espresso",
                  "Americano", "Latte");
  foreach ($drinks as $drink)
  {
    echo "We serve $drink<br/>\n";
  }

?>

If you want to change the value in the array, you can tell the foreach loop to assign the value by reference with the & operator:

<?php

  $drinks = array("Coffee", "Café au Lait", "Mocha", "Espresso",
                  "Americano", "Latte");
  foreach ($drinks as &$drink)
  {
    // mocha is so passé.  we serve iced mocha now.
    if ($drink == "Mocha")
    {
      $drink = "Iced Mocha";
    }
  }

?>

If you would like, you can specify a second variable into which each key associated with those values is placed, separating it from the value's variable with the => operator.

<?php

  $userFavorites = array("car" => "Ferrari", "number" => 21,
                          "city" => "Ouagadougou",
                          "band" => "P.J Harvey");

  foreach ($userFavorites as $thing => $favorite)
  {
    echo "The user's favorite <b>$thing</b>: $favorite<br/>";
  }

?>

The foreach loop has the advantage of being able to handle any keys of any type, including integer-typed ones with gaps. It will likely become the preferred method for iterating over the contents of arrays in your code.

Regular Loops

The for loop, first introduced in Chapter 2, can also be used for iterating over values in an array:

<?php

  $drinks = array("Coffee", "Café au Lait", "Mocha", "Espresso",
                  "Americano", "Latte");

  for ($x = 0; $x < count($drinks); $x++)
  {
    echo "We serve '$drinks[$x]'<br/>\n";
  }

?>

However, the for loop is less flexible than the foreach loop. If your array uses string-based keys, it is more difficult to learn what the key names are. In this case, you should either maintain a list or array of the keys that you wish to query, or call the array_keys method in PHP, which returns an array of all key (index) names within your array.

<?php

  $userFavorites = array("car" => "Ferrari", "number" => 21,
                          "city" => "Ouagadougou",
                          "band" => "P.J Harvey");

  $things = array_keys($userFavorites);
  for ($x = 0; $x < count($things); $x++)
  {
    echo "User's favorite <b>$things[$x]</b>:"
         . $userFavorites[$things[$x]] . "<br/>\n";
  }

?>

If you are using integer-based keys where there are unset gaps or items that have been unset, you cannot just iterate over the integer values. You either need to use the array_keys method again, or check each key index with the isset method to make sure the value exists. We are better served by using the foreach loop.

Internal Loop Counters and each, next, prev, pos, and reset

All PHP arrays maintain an internal array cursor (pointer) that can be used to iterate over the elements in an array when used in conjunction with the each and next methods. To fetch the element currently pointed to by the cursor, you can call the current method (also called pos). To reset it to the first element, you can call the reset method.

The each method is used to traverse the array and fetch values. The method works by returning the element currently pointed to by the cursor and then advancing the cursor to the next element. An array with both the key and value of the specified position is returned by the function. The key can be accessed at key 0 or 'key,' and the value can be accessed at key 1 or 'value.' The method returns FALSE if there are no more elements, (that is, the cursor is past the last element) or if the array is empty.

<?php

   $drinks = array("Coffee", "Café au Lait", "Mocha", "Espresso",
                   "Americano", "Latte");

   reset($drinks);
   while (($item = each($drinks) !== FALSE)
   {
     echo "We serve <b>{$item['value']}</b><br/>\n";
   }

?>

There are a number of methods to iterate over array elements. The next method advances the internal cursor to the next element in the array and then return that element (or FALSE if there are no more). The prev method moves the internal cursor backward by one element and then returns the element at the new position. In both functions, the "element" returned is simply the value instead of the array containing a key/value pair (as seen with the each function). Both next and prev return FALSE when there are no additional elements in the array.

Similar to how the reset function sets the internal cursor to point at the first element, the end method sets the internal cursor to point past the last element:

<?php

  $numbers = array("one", "two", "three", "four");

  //
  // count up
  //
  $item = current($numbers);
  do
  {
    echo "$item ";
  }
  while (($item = next($numbers)) !== FALSE);
  echo "<br/> \n";

  //
  // then down
  //
  end($drinks);
  while (($item = prev($drinks)) !== FALSE)
  {
    echo "$item<br/>\n";
  }

?>

This script produces the output:

one two three four
four three two one

Note that the prev, next, and current (or pos) methods all return the actual value at the current index (and not an array with the key and value dissected like the each method) or FALSE if the cursor is past the last item in the array. If the array has an item with the value FALSE, there will be no means of distinguishing that value from the end of the array when using the current function, nor is there an easy way of determining if an array is empty. Due to such problems, these methods are used infrequently for iterating over arrays.

The array_walk Method

Another way to iterate over all the elements in an array is to use the array_walk method, which takes the array over which to iterate and the name of a function as arguments (see Chapter 3, "Code Organization and Reuse") to call on each of these elements.

In the following example, we use the array_walk function to print the square of all the integer values in an array:

<?php

  function square($in_value, $in_key)
  {
    echo $in_value * $in_value; echo " ";
  }

  $ints = array(1, 2, 3, 4, 5, 6);
  array_walk($ints, 'square');

?>

Our output would be

1 4 9 16 25 36

To have your custom function modify the array, you can use the by reference operator & on the parameter:

<?php

  function square(&$in_value, $in_key)
  {
    $in_value = $in_value * $in_value;
  }

  $ints = array(1, 2, 3, 4, 5, 6);
  var_export($ints); echo "<br/>\n";

  array_walk($ints, 'square');
  var_export($ints); echo "<br/>\n";

?>

After executing this function, our $ints array has been modified to contain the squares of the values it originally contained:

array ( 0 => 1, 1 => 2, 2 => 3, 3 => 4, 4 => 5, 5 => 6, )
array ( 0 => 1, 1 => 4, 2 => 9, 3 => 16, 4 => 25, 5 => 36, )

Also, you can optionally specify a third argumentthis is something passed in to the function each time it is called. The function is called once per item in the array, and it is given as its parameters the value of the current item, the key of the current item, and the optional third argument for the array_walk method.

<?php

  function print_user_favorite($in_value, $in_key, $in_user)
  {
    echo "$in_user's favorite <b>$in_key</b>: $in_value<br/>";
  }

  $userFavorites = array("car" => "Ferrari", "number" => 21,
                          "city" => "Ouagadougou",
                          "band" => "P.J Harvey");
  array_walk($userFavorites, "print_user_favorite", "Bob");

?>


Previous
Table of Contents
Next
© 2000- NIV