start page | rating of books | rating of authors | reviews | copyrights

Programming PHPProgramming PHPSearch this book

5.7. Traversing Arrays

The most common task with arrays is to do something with every element—for instance, sending mail to each element of an array of addresses, updating each file in an array of filenames, or adding up each element of an array of prices. There are several ways to traverse arrays in PHP, and the one you choose will depend on your data and the task you're performing.

5.7.1. The foreach Construct

The most common way to loop over elements of an array is to use the foreach construct:

$addresses = array('[email protected]', '[email protected]');
foreach ($addresses as $value) {
  echo "Processing $value\n";
}
Processing [email protected]
Processing [email protected]

PHP executes the body of the loop (the echo statement) once for each element of $addresses in turn, with $value set to the current element. Elements are processed by their internal order.

An alternative form of foreach gives you access to the current key:

$person = array('name' => 'Fred', 'age' => 35, 'wife' => 'Wilma');
foreach ($person as $k => $v) {
  echo "Fred's $k is $v\n";
}
Fred's name is Fred
Fred's age is 35
Fred's wife is Wilma

In this case, the key for each element is placed in $k and the corresponding value is placed in $v.

The foreach construct does not operate on the array itself, but rather on a copy of it. You can insert or delete elements in the body of a foreach loop, safe in the knowledge that the loop won't attempt to process the deleted or inserted elements.

5.7.2. The Iterator Functions

Every PHP array keeps track of the current element you're working with; the pointer to the current element is known as the iterator. PHP has functions to set, move, and reset this iterator. The iterator functions are:

current( )
Returns the element currently pointed at by the iterator

reset( )
Moves the iterator to the first element in the array and returns it

next( )
Moves the iterator to the next element in the array and returns it

prev( )
Moves the iterator to the previous element in the array and returns it

end( )
Moves the iterator to the last element in the array and returns it

each( )
Returns the key and value of the current element as an array and moves the iterator to the next element in the array

key( )
Returns the key of the current element

The each( ) function is used to loop over the elements of an array. It processes elements according to their internal order:

reset($addresses);
while (list($key, $value) = each($addresses)) {
  echo "$key is $value<BR>\n";
}
0 is [email protected]
1 is [email protected]

This approach does not make a copy of the array, as foreach does. This is useful for very large arrays when you want to conserve memory.

The iterator functions are useful when you need to consider some parts of the array separately from others. Example 5-1 shows code that builds a table, treating the first index and value in an associative array as table column headings.

Example 5-1. Building a table with the iterator functions

$ages = array('Person'  => 'Age',
              'Fred'    => 35,
              'Barney'  => 30,
              'Tigger'  => 8,
              'Pooh'    => 40);
// start table and print heading
reset($ages);
list($c1, $c2) = each($ages);
echo("<table><tr><th>$c1</th><th>$c2</th></tr>\n");
// print the rest of the values
while (list($c1,$c2) = each($ages)) {
  echo("<tr><td>$c1</td><td>$c2</td></tr>\n");
}
// end the table
echo("</table>");
<table><tr><th>Person</th><th>Age</th></tr>
<tr><td>Fred</td><td>35</td></tr>
<tr><td>Barney</td><td>30</td></tr>
<tr><td>Tigger</td><td>8</td></tr>
<tr><td>Pooh</td><td>40</td></tr>
</table>

5.7.3. Using a for Loop

If you know that you are dealing with an indexed array, where the keys are consecutive integers beginning at 0, you can use a for loop to count through the indexes. The for loop operates on the array itself, not on a copy of the array, and processes elements in key order regardless of their internal order.

Here's how to print an array using for:

$addresses = array('[email protected]', '[email protected]');
for($i = 0; $i < count($array); $i++) {
  $value = $addresses[$i];
  echo "$value\n";
}
[email protected]
[email protected]

5.7.4. Calling a Function for Each Array Element

PHP provides a mechanism, array_walk( ), for calling a user-defined function once per element in an array:

array_walk(array, function_name);

The function you define takes in two or, optionally, three arguments: the first is the element's value, the second is the element's key, and the third is a value supplied to array_walk( ) when it is called. For instance, here's another way to print table columns made of the values from an array:

function print_row($value, $key) {
  print("<tr><td>$value</td><td>$key</td></tr>\n");
}
$person = array('name' => 'Fred', 'age' => 35, 'wife' => 'Wilma');
array_walk($person, 'print_row');

A variation of this example specifies a background color using the optional third argument to array_walk( ). This parameter gives us the flexibility we need to print many tables, with many background colors:

function print_row($value, $key, $color) {
  print("<tr><td bgcolor=$color>$value</td><td bgcolor=$color>$key</td></tr>\n");
}
$person = array('name' => 'Fred', 'age' => 35, 'wife' => 'Wilma');
array_walk($person, 'print_row', 'blue');

The array_walk( ) function processes elements in their internal order.

5.7.5. Reducing an Array

A cousin of array_walk( ), array_reduce( ) , applies a function to each element of the array in turn, to build a single value:

$result = array_reduce(array, function_name [, default ]);

The function takes two arguments: the running total, and the current value being processed. It should return the new running total. For instance, to add up the squares of the values of an array, use:

function add_up ($running_total, $current_value) {
  $running_total += $current_value * $current_value;
  return $running_total;
}

$numbers = array(2, 3, 5, 7);
$total = array_reduce($numbers, 'add_up');
// $total is now 87

The array_reduce( ) line makes these function calls:

add_up(2,3)
add_up(13,5)
add_up(38,7)

The default argument, if provided, is a seed value. For instance, if we change the call to array_reduce( ) in the previous example to:

$total = array_reduce($numbers, 'add_up', 11);

The resulting function calls are:

add_up(11,2)
add_up(13,3)
add_up(16,5)
add_up(21,7)

If the array is empty, array_reduce( ) returns the default value. If no default value is given and the array is empty, array_reduce( ) returns NULL.

5.7.6. Searching for Values

The in_array( ) function returns true or false, depending on whether the first argument is an element in the array given as the second argument:

if (in_array(to_find, array [, strict])) { ... }

If the optional third argument is true, the types of to_find and the value in the array must match. The default is to not check the types.

Here's a simple example:

$addresses = array('[email protected]', '[email protected]',
                   '[email protected]');
$got_spam = in_array('[email protected]', $addresses);   // $got_spam is true
$got_milk = in_array('[email protected]', $addresses);       // $got_milk is false

PHP automatically indexes the values in arrays, so in_array( ) is much faster than a loop that checks every value to find the one you want.

Example 5-2 checks whether the user has entered information in all the required fields in a form.

Example 5-2. Searching an array

<?php
 function have_required($array , $required_fields) {
   foreach($required_fields as $field) {
     if(empty($array[$field])) return false;
   }
  
   return true;
 }

 if($submitted) {
   echo '<p>You ';
   echo have_required($_POST, array('name', 'email_address')) ? 'did' : 'did not';
   echo ' have all the required fields.</p>';
 }
?>
<form action="<?= $PHP_SELF; ?>" method="POST">
  <p>
    Name: <input type="text" name="name" /><br />
    Email address: <input type="text" name="email_address" /><br />
    Age (optional): <input type="text" name="age" />
  </p>
  
  <p align="center">
    <input type="submit" value="submit" name="submitted" />
  </p>
</form>

A variation on in_array( ) is the array_search( ) function. While in_array( ) returns true if the value is found, array_search( ) returns the key of the found element:

$person = array('name' => 'Fred', 'age' => 35, 'wife' => 'Wilma');
$k = array_search($person, 'Wilma');
echo("Fred's $k is Wilma\n");
Fred's wife is Wilma

The array_search( ) function also takes the optional third strict argument, which requires the types of the value being searched for and the value in the array to match.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.