|
Date Published: 2002-08-26
This chapter shows you how to use an important programming construct—arrays. The variables that we looked at in the previous chapters are scalar variables, which store a single value. An array is a variable that stores a set or sequence of values. One array can have many elements. Each element can hold a single value, such as text or numbers, or another array. An array containing other arrays is known as a multidimensional array.
PHP and MySQL Web Development (Chapter 3: Using Arrays)
|
 |
Authors: |
Luke Welling and Laura Thomson |
| Publisher: |
Sams |
| ISBN: |
0672317842 |
| Purchase Online: |
Amazon.com |
$34.99 |
| |
Barnes
& Noble |
$39.99 |
Chapter 3: Using Arrays
This chapter shows you how to use an important programming
constructarrays. The variables that we looked at in the previous chapters
are scalar variables, which store a single value. An array is a
variable that stores a set or sequence of values. One array can have many
elements. Each element can hold a single value, such as text or numbers, or
another array. An array containing other arrays is known as a multidimensional
array.
PHP supports both numerically indexed and associative arrays. You will
probably be familiar with numerically indexed arrays if you've used a
programming language, but unless you use PHP or Perl, you might not have seen
associative arrays before. Associative arrays let you use more useful values as
the index. Rather than each element having a numeric index, they can have words
or other meaningful information.
We will continue developing the Bob's Auto parts example using arrays to
work more easily with repetitive information such as customer orders. Likewise,
we will write shorter, tidier code to do some of the things we did with files in
the previous chapter.
Key topics covered in this chapter include
What Is an Array?
We looked at scalar variables in Chapter 1, "PHP Crash Course." A
scalar variable is a named location in which to store a value; similarly, an
array is a named place to store a set of values, thereby allowing you to
group common scalars.
Bob's product list will be the array for our example. In Figure 3.1, you
can see a list of three products stored in an array format and one variable,
called $products, which stores the three values. (We'll look at
how to create a variable like this in a minute.)

Figure 3.1
Bob's products can be stored in an array.
After we have the information as an array, we can do a number of useful
things with it. Using the looping constructs from Chapter 1, we can save work by
performing the same actions on each value in the array. The whole set of
information can be moved around as a single unit. This way, with a single line
of code, all the values can be passed to a function. For example, we might want
to sort the products alphabetically. To achieve this, we could pass the entire
array to PHP's sort() function.
The values stored in an array are called the array elements. Each
array element has an associated index (also called a key) that is
used to access the element.
Arrays in most programming languages have numerical indexes that
typically start from zero or one. PHP supports this type of array.
PHP also supports associative arrays, which will be familiar to Perl
programmers. Associative arrays can have almost anything as the array indices,
but typically use strings.
We will begin by looking at numerically indexed arrays.
Numerically Indexed Arrays
These arrays are supported in most programming languages. In PHP, the indices
start at zero by default, although you can alter this.
Initializing Numerically Indexed Arrays
To create the array shown in Figure 3.1, use the following line of PHP code:
$products = array( "Tires", "Oil", "Spark Plugs" );
This will create an array called products containing the three
values given"Tires", "Oil", and
"Spark Plugs". Note that, like echo,
array() is actually a language construct rather than a function.
Depending on the contents you need in your array, you might not need to
manually initialize them as in the preceding example.
If you have the data you need in another array, you can simply copy one array
to another using the = operator.
If you want an ascending sequence of numbers stored in an array, you can use
the range() function to automatically create the array for you. The
following line of code will create an array called numbers with elements ranging
from 1 to 10:
$numbers = range(1,10);
If you have the information stored in file on disk, you can load the array
contents directly from the file. We'll look at this later in this chapter
under the heading "Loading Arrays from Files."
If you have the data for your array stored in a database, you can load the
array contents directly from the database. This is covered in Chapter 10,
"Accessing Your MySQL Database from the Web with PHP."
You can also use various functions to extract part of an array or to reorder
an array. We'll look at some of these functions later in this chapter,
under the heading "Other Array Manipulations."
Accessing Array Contents
To access the contents of a variable, use its name. If the variable is an
array, access the contents using the variable name and a key or index. The key
or index indicates which stored values we access. The index is placed in square
brackets after the name.
Type $products[0], $products[1], and $products[2]
to use the contents of the products array.
Element zero is the first element in the array. This is the same numbering
scheme as used in C, C++, Java, and a number of other languages, but it might
take some getting used to if you are not familiar with it.
As with other variables, array elements contents are changed by using the
= operator. The following line will replace the first element in the
array "Tires" with "Fuses".
$products[0] = "Fuses";
The following line could be used to add a new
element"Fuse"to the end of the array, giving us a
total of four elements:
$products[3] = "Fuses";
To display the contents, we could type
echo "$products[0] $products[1] $products[2] $products[3]";
Like other PHP variables, arrays do not need to be initialized or created in
advance. They are automatically created the first time you use them.
The following code will create the same $products array:
$products[0] = "Tires";
$products[1] = "Oil";
$products[2] = "Spark Plugs";
If $products does not already exist, the first line will create a
new array with just one element. The subsequent lines add values to the
array.
Using Loops to Access the Array
Because the array is indexed by a sequence of numbers, we can use a
for loop to more easily display the contents:
for ( $i = 0; $i<3; $i++ )
echo "$products[$i] ";
This loop will give similar output to the preceding code, but will require
less typing than manually writing code to work with each element in a large
array. The ability to use a simple loop to access each element is a nice feature
of numerically indexed arrays. Associative arrays are not quite so easy to loop
through, but do allow indexes to be meaningful.
Associative Arrays
In the products array, we allowed PHP to give each item the default index.
This meant that the first item we added became item 0, the second item 1, and so
on. PHP also supports associative arrays. In an associative array, we can
associate any key or index we want with each value.
Initializing an Associative Array
The following code creates an associative array with product names as keys
and prices as values.
$prices = array( "Tires"=>100, "Oil"=>10, "Spark Plugs"=>4 );
Accessing the Array Elements
Again, we access the contents using the variable name and a key, so we can
access the information we have stored in the prices array as $prices[
"Tires" ], $prices[ "Oil" ], and $prices[
"Spark Plugs" ].
Like numerically indexed arrays, associative arrays can be created and
initialized one element at a time.
The following code will create the same $prices array. Rather than
creating an array with three elements, this version creates an array with only
one element, and then adds two more.
$prices = array( "Tires"=>100 );
$prices["Oil"] = 10;
$prices["Spark Plugs"] = 4;
Here is another slightly different, but equivalent piece of code. In this
version, we do not explicitly create an array at all. The array is created for
us when we add the first element to it.
$prices["Tires"] = 100;
$prices["Oil"] = 10;
$prices["Spark Plugs"] = 4;
Using Loops with each() and list()
Because the indices in this associative array are not numbers, we cannot use
a simple counter in a for loop to work with the array. The following
code lists the contents of our $prices array:
while( $element = each( $prices ) )
{
echo $element[ "key" ];
echo " - ";
echo $element[ "value" ];
echo "<br>";
}
The output of this script fragment is shown in Figure 3.2.

Figure 3.2
An each statement can be used to loop through arrays.
In Chapter 1, we looked at while loops and the echo
statement. The preceding code uses the each() function, which we have
not used before. This function returns the current element in an array and makes
the next element the current one. Because we are calling each() within
a while loop, it returns every element in the array in turn and stops
when the end of the array is reached.
In this code, the variable $element is an array. When we call
each(), it gives us an array with four values and the four indexes to
the array locations. The locations key and 0 contain the key
of the current element, and the locations value and 1 contain
the value of the current element. Although it makes no difference which you
choose, we have chosen to use the named locations, rather than the numbered
ones.
There is a more elegant and more common way of doing the same thing. The
function list() can be used to split an array into a number of values.
We can separate two of the values that the each() function gives us
like this:
$list( $product, $price ) = each( $prices );
This line uses each() to take the current element from
$prices, return it as an array, and make the next element current. It
also uses list() to turn the 0 and 1 elements from
the array returned by each() into two new variables called
$product and $price.
We can loop through the entire $prices array, echoing the contents
using this short script.
while ( list( $product, $price ) = each( $prices ) )
echo "$product - $price<br>";
This has the same output as the previous script, but is easier to read
because list() allows us to assign names to the variables.
One thing to note when using each() is that the array keeps track of
the current element. If we want to use the array twice in the same script, we
need to set the current element back to the start of the array using the
function reset(). To loop through the prices array again, we type the
following:
reset($prices);
while ( list( $product, $price ) = each( $prices ) )
echo "$product - $price<br>";
This sets the current element back to the start of the array, and allows us
to go through again.
Multidimensional Arrays
Arrays do not have to be a simple list of keys and valueseach location
in the array can hold another array. This way, we can create a two-dimensional
array. You can think of a two dimensional array as a matrix, or grid, with width
and height or rows and columns.
If we want to store more than one piece of data about each of Bob's
products, we could use a two-dimensional array.
Figure 3.3 shows Bob's products represented as a two-dimensional array
with each row representing an individual product and each column representing
a stored product attribute.

Figure 3.3
We can store more information about Bob's products
in a two-dimensional array.
Using PHP, we would write the following code to set up the data in the array
shown in Figure 3.3.
$products = array( array( "TIR", "Tires", 100 ),
array( "OIL", "Oil", 10 ),
array( "SPK", "Spark Plugs", 4 ) );
You can see from this definition that our products array now contains three
arrays.
To access the data in a one-dimensional array, recall that we need the name
of the array and the index of the element. A two-dimensional array is similar,
except that each element has two indicesa row and a column. (The top row
is row 0 and the far left column is column 0.)
To display the contents of this array, we could manually access each element
in order like this:
echo "|".$products[0][0]."|".$products[0][1]."|".$products[0][2]."|<BR>";
echo "|".$products[1][0]."|".$products[1][1]."|".$products[1][2]."|<BR>";
echo "|".$products[2][0]."|".$products[2][1]."|".$products[2][2]."|<BR>";
Alternatively, we could place a for loop inside another for
loop to achieve the same result.
for ( $row = 0; $row < 3; $row++ )
{
for ( $column = 0; $column < 3; $column++ )
{
echo "|".$products[$row][$column];
}
echo "|<BR>";
}
Both versions of this code produce the same output in the browser:
|TIR|Tires|100|
|OIL|Oil|10|
|SPK|Spark Plugs|4|
The only difference between the two examples is that your code will be
shorter if you use the second version with a large array.
You might prefer to create column names instead of numbers as shown in Figure
3.3. To do this, you can use associative arrays. To store the same set of products,
with the columns named as they are in Figure 3.3, you would use the following
code:
$products = array( array( Code => "TIR",
Description => "Tires",
price => 100
),
array( Code => "OIL",
Description => "Oil",
price => 10
),
array( Code => "SPK",
Description => "Spark Plugs",
price =>4
)
);
This array is easier to work with if you want to retrieve a single value. It
is easier to remember that the description is stored in the Description column
than to remember that it is stored in column 1. Using associative arrays, you do
not need to remember that an item is stored at [x][y]. You can easily find your
data by referring to a location with meaningful row and column names.
We do however lose the ability to use a simple for loop to step
through each column in turn. Here is one way to write code to display this
array:
for ( $row = 0; $row < 3; $row++ )
{
echo "|".$products[$row]["Code"]."|".$products[$row]["Description"].
"|".$products[$row]["Price"]."|<BR>";
}
Using a for loop, we can step through the outer, numerically indexed
$products array. Each row in our $products array is an
associative array. Using the each() and list() functions in
a while loop, we can step through the associative arrays. Therefore, we
need a while loop inside a for loop.
for ( $row = 0; $row < 3; $row++ )
{
while ( list( $key, $value ) = each( $products[ $row ] ) )
{
echo "|$value";
}
echo "|<BR>";
}
We do not need to stop at two dimensionsin the same way that array
elements can hold new arrays, those new arrays in turn can hold more arrays.
A three-dimensional array has height, width, and depth. If you are
comfortable thinking of a two-dimensional array as a table with rows and
columns, imagine a pile or deck of those tables. Each element will be referenced
by its layer, row, and column.
If Bob divided his products into categories, we could use a three-dimensional
array to store them. Figure 3.4 shows Bob's products in a three-dimensional
array.

Figure 3.4
This three-dimensional array allows us to divide products into categories.
From the code that defines this array, you can see that a three-dimensional
array is an array containing arrays of arrays.
$categories = array( array ( array( "TIR", "Tires", 100 ),
array( "OIL", "Oil", 10 ),
array( "SPK", "Spark Plugs", 4 )
),
array ( array( "TIR", "Tires", 100 ),
array( "OIL", "Oil", 10 ),
array( "SPK", "Spark Plugs", 4 )
),
array ( array( "TIR", "Tires", 100 ),
array( "OIL", "Oil", 10 ),
array( "SPK", "Spark Plugs", 4 )
)
);
Because this array has only numeric indices, we can use nested for
loops to display its contents.
for ( $layer = 0; $layer < 3; $layer++ )
{
echo "Layer $layer<BR>";
for ( $row = 0; $row < 3; $row++ )
{
for ( $column = 0; $column < 3; $column++ )
{
echo "|".$categories[$layer][$row][$column];
}
echo "|<BR>";
}
}
Because of the way multidimensional arrays are created, we could create
four-, five-, or six-dimensional arrays. There is no language limit to the
number of dimensions, but it is difficult for people to visualize constructs
with more than three dimensions. Most real-world problems match logically with
constructs of three or fewer dimensions.
Sorting Arrays
It is often useful to sort related data stored in an array. Taking a
one-dimensional array and sorting it into order is quite easy.
Using sort()
The following code results in the array being sorted into ascending
alphabetical order:
$products = array( "Tires", "Oil", "Spark Plugs" );
sort($products);
Our array elements will now be in the order Oil, Spark
Plugs, Tires.
We can sort values by numerical order too. If we have an array containing the
prices of Bob's products, we can sort it into ascending numeric order as
shown:
$prices = array( 100, 10, 4 );
sort($prices);
The prices will now be in the order 4, 10, 100.
Note that the sort function is case sensitive. All capital letters come
before all lowercase letters. So 'A' is less than 'Z', but
'Z' is less than 'a'.
Using asort() and ksort() to Sort Associative
Arrays
If we are using an associative array to store items and their prices, we need
to use different kinds of sort functions to keep keys and values together as
they are sorted.
The following code creates an associative array containing the three products
and their associated prices, and then sorts the array into ascending price
order.
$prices = array( "Tires"=>100, "Oil"=>10, "Spark Plugs"=>4 );
asort($prices);
The function asort() orders the array according to the value of each
element. In the array, the values are the prices and the keys are the textual
descriptions. If instead of sorting by price we want to sort by description, we
use ksort(), which sorts by key rather than value. This code will
result in the keys of the array being ordered alphabeticallyOil,
Spark Plugs, Tires.
$prices = array( "Tires"=>100, "Oil"=>10, "Spark Plugs"=>4 );
ksort($prices);
Sorting in Reverse
You have seen sort(), asort(), and ksort(). These
three different sorting functions all sort an array into ascending order. Each
of these functions has a matching reverse sort function to sort an array into
descending order. The reverse versions are called rsort(),
arsort(), and krsort().
The reverse sort functions are used in the same way as the sorting functions.
The rsort() function sorts a single dimensional numerically indexed
array into descending order. The arsort() function sorts a
one-dimensional associative array into descending order using the value of each
element. The krsort() function sorts a one-dimensional associative
array into descending order using the key of each element.
Sorting Multidimensional Arrays
Sorting arrays with more than one dimension, or by something other than
alphabetical or numerical order, is more complicated. PHP knows how to compare
two numbers or two text strings, but in a multidimensional array, each element
is an array. PHP does not know how to compare two arrays, so you need to create
a method to compare them. Most of the time, the order of the words or numbers is
fairly obviousbut for complicated objects, it becomes more
problematic.
User Defined Sorts
Here is the definition of a two-dimensional array we used earlier. This array
stores Bob's three products with a code, a description, and a price for
each.
$products = array( array( "TIR", "Tires", 100 ),
array( "OIL", "Oil", 10 ),
array( "SPK", "Spark Plugs", 4 ) );
If we sort this array, what order will the values end up in? Because we know
what the contents represent, there are at least two useful orders. We might want
the products sorted into alphabetical order using the description or by numeric
order by the price. Either result is possible, but we need to use the function
usort() and tell PHP how to compare the items. To do this, we need to
write our own comparison function.
The following code sorts this array into alphabetical order using the second
column in the arraythe description.
function compare($x, $y)
{
if ( $x[1] == $y[1] )
return 0;
else if ( $x[1] < $y[1] )
return -1;
else
return 1;
}
usort($products, compare);
So far in this book, we have called a number of the built-in PHP functions.
To sort this array, we have defined a function of our own. We will examine
writing functions in detail in Chapter 5, "Reusing Code and Writing
Functions," but here is a brief introduction.
We define a function using the keyword function. We need to give the
function a name. Names should be meaningful, so we'll call it
compare(). Many functions take parameters or arguments. Our
compare() function takes two, one called x and one called
y. The purpose of this function is to take two values and determine
their order.
For this example, the x and y parameters will be two of the
arrays within the main array, each representing one product. To access the Description
of the array x, we type $x[1] because the Description
is the second element in these arrays, and numbering starts at zero. We use
$x[1] and $y[1] to compare the Descriptions from
the arrays passed into the function.
When a function ends, it can give a reply to the code that called it. This is
called returning a value. To return a value, we use the keyword
return in our function. For example, the line return 1; sends
the value 1 back to the code that called the function.
To be used by usort(), the compare() function must compare
x and y. The function must return 0 if x
equals y, a negative number if it is less, and a positive number if it
is greater. Our function will return 0, 1, or
1, depending on the values of x and y.
The final line of code calls the built-in function usort() with the
array we want sorted ($products) and the name of our comparison
function (compare()).
If we want the array sorted into another order, we can simply write a
different comparison function. To sort by price, we need to look at the third
column in the array, and create this comparison function:
function compare($x, $y)
{
if ( $x[2] == $y[2] )
return 0;
else if ( $x[2] < $y[2] )
return -1;
else
return 1;
}
When usort($products, compare) is called, the array will be placed
in ascending order by price.
The "u" in usort() stands for "user" because
this function requires a user-defined comparison function. The uasort()
and uksort() versions of asort and ksort also require
a user-defined comparison function.
Similar to asort(), uasort() should be used when sorting an
associative array by value. Use asort if your values are simple numbers
or text. Define a comparison function and use uasort() if your values
are more complicated objects such as arrays.
Similar to ksort(), uksort() should be used when sorting an
associative array by key. Use ksort if your keys are simple numbers or
text. Define a comparison function and use uksort() if your keys are
more complicated objects such as arrays.
Reverse User Sorts
The functions sort(), asort(), and ksort() all
have a matching reverse sort with an "r" in the function name. The
user-defined sorts do not have reverse variants, but you can sort a
multidimensional array into reverse order. You provide the comparison function,
so write a comparison function that returns the opposite values. To sort into
reverse order, the function will need to return 1 if x is less
than y and 1 if x is greater than y.
For example
function reverseCompare($x, $y)
{
if ( $x[2] == $y[2] )
return 0;
else if ( $x[2] < $y[2] )
return 1;
else
return -1;
}
Calling usort($products, reverseCompare) would now result in the
array being placed in descending order by price.
Reordering Arrays
For some applications, you might want to manipulate the order of the array in
other ways. The function shuffle() randomly reorders the elements of
your array. The function array_reverse() gives you a copy of your array
with all the elements in reverse order.
Using shuffle()
Bob wants to feature a small number of his products on the front page of his
site. He has a large number of products, but would like three randomly selected
items shown on the front page. So that repeat visitors do not get bored, he
would like the three chosen products to be different for each visit. He can
easily accomplish his goal if all his products are in an array. Listing 3.1
displays three randomly chosen pictures by shuffling the array into a random
order and then displaying the first three.
Listing 3.1 bobs_front_page.phpUsing PHP to Produce a Dynamic Front
Page for Bob's Auto Parts
<?
$pictures = array("tire.jpg", "oil.jpg", "spark_plug.jpg",
"door.jpg", "steering_wheel.jpg",
"thermostat.jpg", "wiper_blade.jpg",
"gasket.jpg", "brake_pad.jpg");
shuffle($pictures);
?>
<html>
<head>
<title>Bob's Auto Parts</title>
</head>
<body>
<center>
<h1>Bob's Auto Parts</H1>
<table width = 100%>
<tr>
<?
for ( $i = 0; $i < 3; $i++ )
{
echo "<td align = center><img src=\"";
echo $pictures[$i];
echo "\" width = 100 height = 100></td>";
}
?>
</tr>
</table>
</center>
</body>
</html>
Because the code selects random pictures, it produces a different page nearly
every time you load it, as shown in Figure 3.5.

Figure 3.5
The shuffle() function enables us to feature three randomly
chosen products.
Using array_reverse()
The function array_reverse() takes an array and creates a new one
with the same contents in reverse order. For example, there are a number of ways
to create an array containing a countdown from ten to one.
Because using range() alone creates an ascending sequence, we must
then use rsort() to sort the numbers into descending order.
Alternatively, we could create the array one element at a time by writing a
for loop:
$numbers = array();
for($i=10; $i>0; $i--)
array_push( $numbers, $i );
A for() loop can go in descending order like this. We set the
starting value high, and at the end of each loop use the -- operator to
decrease the counter by one.
We created an empty array, and then used array_push() for each
element to add one new element to the end of an array. As a side note, the
opposite of array_push() is array_pop(). This function removes
and returns one element from the end of an array.
Alternatively, we can use the array_reverse() function to reverse
the array created by range().
$numbers = range(1,10);
$numbers = array_reverse($numbers);
Note that array_reverse() returns a modified copy of the array.
Because we did not want the original array, we simply stored the new copy over
the original.
Loading Arrays from Files
In Chapter 2, "Storing and Retrieving Data," we stored customer
orders in a file. Each line in the file looks something like
15:42, 20th April 4 tires 1 oil 6 spark plugs $434.00 22 Short St, Smalltown
To process or fulfill this order, we could load it back into an array.
Listing 3.2 displays the current order file.
Listing 3.2 vieworders.phpUsing PHP to Display Orders for Bob
$orders= file("../../orders/orders.txt");
$number_of_orders = count($orders);
if ($number_of_orders == 0)
{
echo "<p><strong>No orders pending.
Please try again later.</strong></p>";
}
for ($i=0; $i<$number_of_orders; $i++)
{
echo $orders[$i]."<br>";
}
This script produces almost exactly the same output as Listing 2.2 in the
previous chapter, which is shown in Figure 2.4. This time, we are using the
function file(), which loads the entire file into an array. Each line
in the file becomes one element of an array.
This code also uses the count() function to see how many elements
are in an array.
Furthermore, we could load each section of the order lines into separate
array elements to process the sections separately or to format them more
attractively. Listing 3.3 does exactly that.
Listing 3.3 vieworders2.phpUsing PHP to Separate, Format, and
Display Orders for Bob
<html>
<head>
<title>Bob's Auto Parts Customer Orders</title>
</head>
<body>
<h1>Bob's Auto Parts</h1>
<h2>Customer Orders</h2>
<?
//Read in the entire file.
//Each order becomes an element in the array
$orders= file("../../orders/orders.txt");
// count the number of orders in the array
$number_of_orders = count($orders);
if ($number_of_orders == 0)
{
echo "<p><strong>No orders pending.
Please try again later.</strong></p>";
}
echo "<table border=1>\n";
echo "<tr><th bgcolor = \"#CCCCFF\">Order Date</td>
<th bgcolor = \"#CCCCFF\">Tires</td>
<th bgcolor = \"#CCCCFF\">Oil</td>
<th bgcolor = \"#CCCCFF\">Spark Plugs</td>
<th bgcolor = \"#CCCCFF\">Total</td>
<th bgcolor = \"#CCCCFF\">Address</td>
<tr>";
for ($i=0; $i<$number_of_orders; $i++)
{
//split up each line
$line = explode( "\t", $orders[$i] );
// keep only the number of items ordered
$line[1] = intval( $line[1] );
$line[2] = intval( $line[2] );
$line[3] = intval( $line[3] );
// output each order
echo "<tr><td>$line[0]</td>
<td align = right>$line[1]</td>
<td align = right>$line[2]</td>
<td align = right>$line[3]</td>
<td align = right>$line[4]</td>
<td>$line[5]</td>
</tr>";
}
echo "</table>";
?>
</body>
</html>
The code in Listing 3.3 loads the entire file into an array but unlike the
example in Listing 3.2, here we are using the function explode() to
split up each line, so that we can apply some processing and formatting before
printing.
The output from this script is shown in Figure 3.6.

Figure 3.6
After splitting order records with explode, we can put each
part of an order in a different table cell for better looking output.
The explode function has the following prototype:
array explode(string separator, string string)
In the previous chapter, we used the tab character as a delimiter when
storing this data, so here we called
explode( "\t", $orders[$i] )
This "explodes" the passed-in string into parts. Each tab character
becomes a break between two elements. For example, the string
"15:42, 20th April\t4 tires\t1 oil\t
6 spark plugs\t$434.00\t22 Short St, Smalltown"
is exploded into the parts "15:42, 20th April",
"4 tires", "1 oil", "6 spark
plugs", "$434.00", and "22 Short St,
Smalltown".
We have not done very much processing here. Rather than output tires, oil,
and spark plugs on every line, we are only displaying the number of each and
giving the table a heading row to show what the numbers represent.
There are a number of ways that we could have extracted numbers from these
strings. Here we used the function, intval(). As mentioned in Chapter
1, intval() converts a string to an integer. The
conversion is reasonably clever and will ignore parts, such as the label in this
example, that cannot be converted to an integer. We will cover various
ways of processing strings in the next chapter.
Other Array Manipulations
So far, we have only covered about half the array processing functions. Many
others will be useful from time to time.
Navigating Within an Array: each, current(),
reset(), end(), next(), pos(), and prev()
We mentioned previously that every array has an internal pointer that points
to the current element in the array. We indirectly used this pointer earlier
when using the each() function, but we can directly use and manipulate
this pointer.
If we create a new array, the current pointer is initialized to point to the
first element in the array. Calling current( $array_name ) returns the
first element.
Calling either next() or each() advances the pointer
forward one element. Calling each( $array_name ) returns the current
element before advancing the pointer. The function next() behaves
slightly differentlycalling next( $array_name ) advances the
pointer and then returns the new current element.
We have already seen that reset() returns the pointer to the first
element in the array. Similarly, calling end( $array_name ) sends the
pointer to the end of the array. The first and last element in the array are
returned by reset() and end(), respectively.
To move through an array in reverse order, we could use end() and
prev(). The prev() function is the opposite of
next(). It moves the current pointer back one and then returns the new
current element.
For example, the following code displays an array in reverse order:
$value = end ($array);
while ($value)
{
echo "$value<br>";
$value = prev($array);
}
If $array was declared like this:
$array = array(1, 2, 3);
the output would appear in a browser as
3
2
1
Using each(), current(), reset(), end(),
next(), pos(), and prev(), you can write your own
code to navigate through an array in any order.
Applying Any Function to Each Element in an Array:
array_walk()
Sometimes you might want to work with or modify every element in an array in
the same way. The function array_walk() allows you to do this.
The prototype of array_walk() is as follows:
int array_walk(array arr, string func, [mixed userdata])
Similar to the way we called usort() earlier, array_walk()
expects you to declare a function of your own.
As you can see, array_walk() takes three parameters. The first, arr,
is the array to be processed. The second, func, is the name of a user-defined
function that will be applied to each element in the array. The third parameter,
userdata, is optional. If you use it, it will be passed through to your function
as a parameter. You'll see how this works in a minute.
A handy user-defined function might be one that displays each element with
some specified formatting.
The following code displays each element on a new line by calling the
user-defined function myPrint() with each element of
$array:
function myPrint($value)
{
echo "$value<BR>";
}
array_walk($array, myPrint);
The function you write needs to have a particular signature. For each element
in the array, array_walk takes the key and value stored in the array,
and anything you passed as userdata, and calls your function like this:
Yourfunction(value, key, userdata)
For most uses, your function will only be using the values in the array. For
some, you might also need to pass a parameter to your function using the
parameter userdata. Occasionally, you might be interested in the key of each
element as well as the value. Your function can, as with MyPrint(),
choose to ignore the key and userdata parameter.
For a slightly more complicated example, we will write a function that
modifies the values in the array and requires a parameter. Note that although we
are not interested in the key, we need to accept it in order to accept the third
parameter.
function myMultiply(&$value, $key, $factor)
{
$value *= $factor;
}
array_walk(&$array, "myMultiply", 3);
Here we are defining a function, myMultiply(), that will multiply
each element in the array by a supplied factor. We need to use the optional
third parameter to array_walk() to take a parameter to pass to our
function and use it as the factor to multiply by. Because we need this
parameter, we must define our function, myMultiply(), to take three
parametersan array element's value ($value), an array
element's key ($key), and our parameter ($factor). We are
choosing to ignore the key.
A subtle point to note is the way we pass $value. The ampersand
(&) before the variable name in the definition of
myMultiply() means that $value will be passed by
reference. Passing by reference allows the function to alter the contents of
the array.
We will address passing by reference in more detail in Chapter 5. If you are
not familiar with the term, for now just note that to pass by reference, we
place an ampersand before the variable name.
Counting Elements in an Array: count(), sizeof(),
and array_count_values()
We used the function count() in an earlier example to count the
number of elements in an array of orders. The function sizeof() has
exactly the same purpose. Both these functions return the number of elements in
an array passed to them. You will get a count of one for the number of elements
in a normal scalar variable and 0 if you pass either an empty array or a
variable that has not been set.
The array_count_values() function is more complex. If you call
array_count_values($array), this function counts how many times each
unique value occurs in the array $array. (This is the set
cardinality of the array.) The function returns an associative array containing
a frequency table. This array contains all the unique values from
$array as keys. Each key has a numeric value that tells you how many
times the corresponding key occurs in $array.
For example, the following code
$array = array(4, 5, 1, 2, 3, 1, 2, 1);
$ac = array_count_values($array);
creates an array called $ac that contains
|
Key
|
Value
|
|
4
|
1
|
|
5
|
1
|
|
1
|
3
|
|
2
|
2
|
|
3
|
1
|
This indicates that 4, 5, and 3 occurred once in
$array, 1 occurred three times, and 2 occurred twice.
Converting Arrays to Scalar Variables:
extract()
If we have an associative array with a number of key value pairs, we can turn
them into a set of scalar variables using the function extract(). The
prototype for extract() is as follows:
extract(array var_array [, int extract_type] [, string prefix] );
The purpose of extract() is to take an array and create scalar
variables with the names of the keys in the array. The values of these variables
are set to the values in the array.
Here is a simple example.
$array = array( "key1" => "value1", "key2" => "value2", "key3" => "value3");
extract($array);
echo "$key1 $key2 $key3";
This code produces the following output:
value1 value2 value3
The array had three elements with keys: key1, key2, and
key3. Using extract(), we created three scalar variables,
$key1, $key2, and $key3. You can see from the output
that the values of $key1, $key2, and $key3 are
"value1", "value2", and
"value3", respectively. These values came from the original
array.
There are two optional parameters to extract(): extract_type and
prefix. The variable extract_type tells extract() how to
handle collisions. These are cases in which a variable already exists with the
same name as a key. The default response is to overwrite the existing variable.
Four allowable values for extract_type are shown in Table 3.1.
Table 3.1 Allowed extract_types for extract()
|
Type
|
Meaning
|
|
EXTR_OVERWRITE
|
Overwrites the existing variable when a collision occurs.
|
|
EXTR_SKIP
|
Skips an element when a collision occurs.
|
|
EXTR_PREFIX_SAME
|
Creates a variable named $prefix_key when a collision occurs.
You must supply prefix.
|
|
EXTR_PREFIX_ALL
|
Prefixes all variable names with prefix. You must supply prefix.
|
The two most useful options are the default
(EXTR_OVERWRITE) and EXTR_PREFIX_ALL. The other two options
might be useful occasionally when you know that a particular collision will
occur and want that key skipped or prefixed. A simple example using
EXTR_PREFIX_ALL follows. You can see that the variables created are
called prefix-underscore-keyname.
$array = array( "key1" => "value1", "key2" => "value2", "key3" => "value3");
extract($array, EXTR_PREFIX_ALL, "myPrefix");
echo "$myPrefix_key1 $myPrefix_key2 $myPrefix_key3";
This code will again produce the output: value1 value2 value3.
Note that for extract() to extract an element, that element's
key must be a valid variable name, which means that keys starting with numbers
or including spaces will be skipped.
Further Reading
This chapter covers what we believe to be the most useful of PHP's array
functions. We have chosen not to cover all the possible array functions. The
online PHP manual available at
http://www.php.net has a brief
description of each of them.
Next
In the next chapter, we look at string processing functions. We will cover
functions that search, replace, split, and merge strings, as well as the
powerful regular expression functions that can perform almost any action on a
string.
© Copyright Pearson Education. All rights reserved.
|