Chapter 4. Groups of Data: Working with Arrays
Arrays are collections of related values, such as the data submitted from a form, the names of students in a class, or the populations of a list of cities. In Chapter 2, you learned that a variable is a named container that holds a value. An array is a container that holds multiple values.
This chapter shows you how to work with arrays. The next section, “Array Basics”, goes over
fundamentals such as how to create arrays and manipulate their
elements. Frequently, you’ll want to do something
with each element in an array, such as print it or inspect it for
certain conditions. “Looping Through Arrays” explains how to do these
things with the foreach()
and for()
constructs. “Modifying Arrays” introduces the
implode()
and explode()
functions, which turn arrays into strings and strings into arrays.
Another kind of array modification is sorting, which is discussed in
“Sorting Arrays”. Finally, “Using Multidimensional Arrays” explores arrays that contain other arrays.
Working with arrays is a common PHP programming task. Chapter 7 shows you how to process form data, which the PHP engine automatically puts into an array for you. When you retrieve information from a database as described in Chapter 8, that data is often packaged into an array. Being comfortable with arrays makes it easy for you to manipulate these kinds of data.
Array Basics
An array is made up of elements. Each element has a key and a value. For example, an array holding information about the colors of vegetables has vegetable names for keys and colors for values, as shown in Figure 4-1.
An array can only have one element with a given key. In the
vegetable color array, there can’t be another element with the key corn
even if its value is blue
. However,
the same value can appear many times in one array. You can have green peppers, green broccoli, and green celery.
Any string or number value can be an array element key, such as
corn
, 4
,
-36
, or Salt
Baked
Squid
. Arrays and other
nonscalar1 values can’t be
keys, but they can be element values. An element value can be anything: a
string, a number, true
, false
, or a nonscalar type such as another array.
Creating an Array
To create an array, use the array()
language construct. Specify a comma-delimited list of key/value pairs, with the key and the value separated by =>
. This is shown in Example 4-1.
Example 4-1. Creating an array
$vegetables
=
array
(
'corn'
=>
'yellow'
,
'beet'
=>
'red'
,
'carrot'
=>
'orange'
);
$dinner
=
array
(
0
=>
'Sweet Corn and Asparagus'
,
1
=>
'Lemon Chicken'
,
2
=>
'Braised Bamboo Fungus'
);
$computers
=
array
(
'trs-80'
=>
'Radio Shack'
,
2600
=>
'Atari'
,
'Adam'
=>
'Coleco'
);
The array keys and values in Example 4-1 are strings
(such as corn
, Braised Bamboo
Fungus
, and Coleco
) and numbers
(such as 0
, 1
, and
2600
). They are written just like other strings
and numbers in PHP programs: with quotes around the strings but not
around the numbers.
A shortcut for the array()
language construct is a pair of square brackets (called the short array syntax). Example 4-2 creates the same arrays as Example 4-1 but with the short array syntax.
Example 4-2. Using short array syntax
$vegetables
=
[
'corn'
=>
'yellow'
,
'beet'
=>
'red'
,
'carrot'
=>
'orange'
];
$dinner
=
[
0
=>
'Sweet Corn and Asparagus'
,
1
=>
'Lemon Chicken'
,
2
=>
'Braised Bamboo Fungus'
];
$computers
=
[
'trs-80'
=>
'Radio Shack'
,
2600
=>
'Atari'
,
'Adam'
=>
'Coleco'
];
Warning
The short array syntax was introduced in PHP 5.4. If you’re using an earlier version of PHP, you need to stick with array()
.
You can also add elements to an array one at a time by assigning a value to a particular array key. Example 4-3 builds the same arrays as the previous two examples but does it element by element.
Example 4-3. Creating an array element by element
// An array called $vegetables with string keys
$vegetables
[
'corn'
]
=
'yellow'
;
$vegetables
[
'beet'
]
=
'red'
;
$vegetables
[
'carrot'
]
=
'orange'
;
// An array called $dinner with numeric keys
$dinner
[
0
]
=
'Sweet Corn and Asparagus'
;
$dinner
[
1
]
=
'Lemon Chicken'
;
$dinner
[
2
]
=
'Braised Bamboo Fungus'
;
// An array called $computers with numeric and string keys
$computers
[
'trs-80'
]
=
'Radio Shack'
;
$computers
[
2600
]
=
'Atari'
;
$computers
[
'Adam'
]
=
'Coleco'
;
In Example 4-3, the square brackets after the array’s variable name reference a particular key in the array. By assigning a value to that key, you create an element in the array.
Choosing a Good Array Name
Names for variables holding arrays follow the same rules as names
for any other variables. Names for arrays and scalar variables come
from the same pool of possible names, so you can’t have an array
called
$vegetables
and a scalar called
$vegetables
at the same time. If you assign a scalar value to an array (or vice versa), the old value is silently wiped out and the variable becomes the new value. In Example 4-4, $vegetables
becomes a
scalar, and $fruits
becomes an array.
Example 4-4. Array and scalar collision
// This makes $vegetables an array
$vegetables
[
'corn'
]
=
'yellow'
;
// This removes any trace of "corn" and "yellow" and makes $vegetables a scalar
$vegetables
=
'delicious'
;
// This makes $fruits a scalar
$fruits
=
283
;
// This doesn't work -- $fruits stays 283 and the PHP engine
// issues a warning
$fruits
[
'potassium'
]
=
'banana'
;
// But this overwrites $fruits and it becomes an array
$fruits
=
array
(
'potassium'
=>
'banana'
);
In Example 4-1, the $vegetables
and $computers
arrays each store a list of
relationships. The $vegetables
array relates
vegetables and colors, while the $computers
array
relates computer names and manufacturers. In the
$dinner
array, however, we just care about the
names of dishes that are the array values. The array keys are just
numbers that distinguish one element from another.
Creating a Numeric Array
PHP provides some shortcuts for working with arrays that have only
numbers as keys. If you create an array with []
or array()
by specifying only a list of values instead of key/value pairs, the PHP
engine automatically assigns a numeric key to each value. The
keys start at 0
and increase by one for each element. Example 4-5 uses this technique to create the
$dinner
array.
Example 4-5. Creating numeric arrays with array()
$dinner
=
array
(
'Sweet Corn and Asparagus'
,
'Lemon Chicken'
,
'Braised Bamboo Fungus'
);
"I want
$dinner[0]
and
$dinner[1]
."
;
Example 4-5 prints:
I want Sweet Corn and Asparagus and Lemon Chicken.
Internally, the PHP engine treats arrays with numeric keys and arrays with string keys (and arrays with a mix of numeric and string keys) identically. Because of the resemblance to features in other programming languages, programmers often refer to arrays with only numeric keys as “numeric,” “indexed,” or “ordered” arrays, and to string-keyed arrays as “associative” arrays. An associative array, in other words, is one whose keys signify something other than the positions of the values within the array. Each key is associated with its value.
PHP automatically uses incrementing numbers for array keys when you create an array or add elements to an array with the empty brackets syntax shown in Example 4-6.
Example 4-6. Adding elements with []
// Create $lunch array with two elements
// This sets $lunch[0]
$lunch
[]
=
'Dried Mushrooms in Brown Sauce'
;
// This sets $lunch[1]
$lunch
[]
=
'Pineapple and Yu Fungus'
;
// Create $dinner with three elements
$dinner
=
array
(
'Sweet Corn and Asparagus'
,
'Lemon Chicken'
,
'Braised Bamboo Fungus'
);
// Add an element to the end of $dinner
// This sets $dinner[3]
$dinner
[]
=
'Flank Skin with Spiced Flavor'
;
The empty brackets add an element to the array. The new element has a
numeric key that’s one more than the biggest numeric
key already in the array. If the array doesn’t exist
yet, the empty brackets add an element with a key of
0
.
Warning
Making the first element have key 0
, not key
1
, is not in line with how normal humans (in
contrast to computer programmers) think, so it bears repeating. The
first element of an array with numeric keys is element
0
, not element 1
.
Finding the Size of an Array
The count()
function tells you the number of elements in an
array. Example 4-7
demonstrates count()
.
Example 4-7. Finding the size of an array
$dinner
=
array
(
'Sweet Corn and Asparagus'
,
'Lemon Chicken'
,
'Braised Bamboo Fungus'
);
$dishes
=
count
(
$dinner
);
"There are
$dishes
things for dinner."
;
Example 4-7 prints:
There are 3 things for dinner.
When you pass it an empty array (that is, an array with no
elements in it), count()
returns 0
. An empty
array also evaluates to false
in an if()
test expression.
Looping Through Arrays
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'
);
"<table>
\n
"
;
foreach
(
$meal
as
$key
=>
$value
)
{
"<tr><td>
$key
</td><td>
$value
</td></tr>
\n
"
;
}
'</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'
);
"<table>
\n
"
;
foreach
(
$meal
as
$key
=>
$value
)
{
'<tr class="'
.
$row_styles
[
$style_index
]
.
'">'
;
"<td>
$key
</td><td>
$value
</td></tr>
\n
"
;
// This switches $style_index between 0 and 1
$style_index
=
1
-
$style_index
;
}
'</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
)
{
"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 element 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 variable
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
=
0
,
$num_dishes
=
count
(
$dinner
);
$i
<
$num_dishes
;
$i
++
)
{
"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_styles
=
array
(
'even'
,
'odd'
);
$dinner
=
array
(
'Sweet Corn and Asparagus'
,
'Lemon Chicken'
,
'Braised Bamboo Fungus'
);
"<table>
\n
"
;
for
(
$i
=
0
,
$num_dishes
=
count
(
$dinner
);
$i
<
$num_dishes
;
$i
++
)
{
'<tr class="'
.
$row_styles
[
$i
%
2
]
.
'">'
;
"<td>Element
$i
</td><td>
$dinner[$i]
</td></tr>
\n
"
;
}
'</table>'
;
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 separate 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 elements in numeric or alphabetic order.
Example 4-14. Array element order and foreach()
$letters
[
0
]
=
'A'
;
$letters
[
1
]
=
'B'
;
$letters
[
3
]
=
'D'
;
$letters
[
2
]
=
'C'
;
foreach
(
$letters
as
$letter
)
{
$letter
;
}
Example 4-14 prints:
ABDC
To guarantee that elements are accessed in numerical key order, use
for()
to iterate through the loop:
for
(
$i
=
0
,
$num_letters
=
count
(
$letters
);
$i
<
$num_letters
;
$i
++
)
{
$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
(
'Walnut 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
))
{
"Yes, we have Shrimp Puffs"
;
}
// This is false
if
(
array_key_exists
(
'Steak Sandwich'
,
$meals
))
{
"We have a Steak Sandwich"
;
}
// This is true
if
(
array_key_exists
(
1
,
$books
))
{
"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
(
3
,
$meals
))
{
'There is a $3 item.'
;
}
// This is true
if
(
in_array
(
'How to Cook and Eat in Chinese'
,
$books
))
{
"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
))
{
"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
(
6.50
,
$meals
);
if
(
$dish
)
{
"
$dish
costs
\$
6.50"
;
}
Example 4-17 prints:
Eggplant with Chili Sauce costs $6.50
Modifying Arrays
You can operate on individual array elements just like regular scalar variables, using arithmetic, logical, and other operators. Example 4-18 shows some operations on array elements.
Example 4-18. Operating on array elements
$dishes
[
'Beef Chow Foon'
]
=
12
;
$dishes
[
'Beef Chow Foon'
]
++
;
$dishes
[
'Roast Duck'
]
=
3
;
$dishes
[
'total'
]
=
$dishes
[
'Beef Chow Foon'
]
+
$dishes
[
'Roast Duck'
];
if
(
$dishes
[
'total'
]
>
15
)
{
"You ate a lot: "
;
}
'You ate '
.
$dishes
[
'Beef Chow Foon'
]
.
' dishes of Beef Chow Foon.'
;
Example 4-18 prints:
You ate a lot: You ate 13 dishes of Beef Chow Foon.
Interpolating array element values in double-quoted strings or here documents is similar to interpolating numbers or strings. The easiest way is to include the array element in the string, but don’t put quotes around the element key. This is shown in Example 4-19.
Example 4-19. Interpolating array element values in double-quoted strings
$meals
[
'breakfast'
]
=
'Walnut Bun'
;
$meals
[
'lunch'
]
=
'Eggplant with Chili Sauce'
;
$amounts
=
array
(
3
,
6
);
"For breakfast, I'd like
$meals[breakfast]
and for lunch,
\n
"
;
"I'd like
$meals[lunch]
. I want
$amounts[0]
at breakfast and
\n
"
;
"
$amounts[1]
at lunch."
;
Example 4-19 prints:
For breakfast, I'd like Walnut Bun and for lunch, I'd like Eggplant with Chili Sauce. I want 3 at breakfast and 6 at lunch.
The interpolation in Example 4-19 works only with array keys that consist exclusively of letters, numbers, and underscores. If you have an array key that has whitespace or other punctuation in it, interpolate it with curly braces, as demonstrated in Example 4-20.
Example 4-20. Interpolating array element values with curly braces
$meals
[
'Walnut Bun'
]
=
'$3.95'
;
$hosts
[
'www.example.com'
]
=
'website'
;
"A Walnut Bun costs
{
$meals
[
'Walnut Bun'
]
}
.
\n
"
;
"www.example.com is a
{
$hosts
[
'www.example.com'
]
}
."
;
Example 4-20 prints:
A Walnut Bun costs $3.95. www.example.com is a website.
In a double-quoted string or here document, an expression inside curly braces is evaluated and then its value is put into the string. In Example 4-20, the expressions used are lone array elements, so the element values are interpolated into the strings.
To remove an element from an array, use unset()
:
unset
(
$dishes
[
'Roast Duck'
]);
Removing an element with unset()
is different
than just setting the element value to 0
or the
empty string. When you use unset()
, the element
is no longer there when you iterate through the array or count the
number of elements in the array. Using unset()
on
an array that represents a store’s inventory is like
saying that the store no longer carries a product. Setting the
element’s value to 0
or the empty
string says that the item is temporarily out of stock.
When you want to print all of the values in an array at once, the
quickest way is to use the implode()
function. It makes a string by
combining all the values in an array, putting a string delimiter between each value. Example 4-21 prints a
comma-separated list of dim sum choices.
Example 4-21. Making a string from an array with implode()
$dimsum
=
array
(
'Chicken Bun'
,
'Stuffed Duck Web'
,
'Turnip Cake'
);
$menu
=
implode
(
', '
,
$dimsum
);
$menu
;
Example 4-21 prints:
Chicken Bun, Stuffed Duck Web, Turnip Cake
To implode an array with no delimiter, use the empty string as the
first argument to implode()
:
$letters
=
array
(
'A'
,
'B'
,
'C'
,
'D'
);
implode
(
''
,
$letters
);
This prints:
ABCD
Use implode()
to simplify printing HTML table
rows, as shown in Example 4-22.
Example 4-22. Printing HTML table rows with implode()
$dimsum
=
array
(
'Chicken Bun'
,
'Stuffed Duck Web'
,
'Turnip Cake'
);
'<tr><td>'
.
implode
(
'</td><td>'
,
$dimsum
)
.
'</td></tr>'
;
Example 4-22 prints:
<tr><td>
Chicken Bun</td><td>
Stuffed Duck Web</td><td>
Turnip Cake</td></tr>
The implode()
function puts its delimiter between
each value, so to make a complete table row, you also have to print
the opening tags that go before the first element and the closing
tags that go after the last element.
The counterpart to implode()
is called explode()
. It breaks a string apart into an array. The delimiter argument to
explode()
is the string it should look for to
separate array elements. Example 4-23 demonstrates
explode()
.
Example 4-23. Turning a string into an array with explode()
$fish
=
'Bass, Carp, Pike, Flounder'
;
$fish_list
=
explode
(
', '
,
$fish
);
"The second fish is
$fish_list[1]
"
;
Example 4-23 prints:
The second fish is Carp
Sorting Arrays
There are several ways to sort arrays. Which function to use depends on how you want to sort your array and what kind of array it is.
The sort()
function
sorts an array by its element values. It should only be used on
numeric arrays, because it resets the keys of the array when it
sorts. Example 4-24 shows some arrays before and
after sorting.
Example 4-24. Sorting with sort()
$dinner
=
array
(
'Sweet Corn and Asparagus'
,
'Lemon Chicken'
,
'Braised Bamboo Fungus'
);
$meal
=
array
(
'breakfast'
=>
'Walnut Bun'
,
'lunch'
=>
'Cashew Nuts and White Mushrooms'
,
'snack'
=>
'Dried Mulberries'
,
'dinner'
=>
'Eggplant with Chili Sauce'
);
"Before Sorting:
\n
"
;
foreach
(
$dinner
as
$key
=>
$value
)
{
"
\$
dinner:
$key
$value\n
"
;
}
foreach
(
$meal
as
$key
=>
$value
)
{
"
\$
meal:
$key
$value\n
"
;
}
sort
(
$dinner
);
sort
(
$meal
);
"After Sorting:
\n
"
;
foreach
(
$dinner
as
$key
=>
$value
)
{
"
\$
dinner:
$key
$value\n
"
;
}
foreach
(
$meal
as
$key
=>
$value
)
{
"
\$
meal:
$key
$value\n
"
;
}
Example 4-24 prints:
Before Sorting: $dinner: 0 Sweet Corn and Asparagus $dinner: 1 Lemon Chicken $dinner: 2 Braised Bamboo Fungus $meal: breakfast Walnut Bun $meal: lunch Cashew Nuts and White Mushrooms $meal: snack Dried Mulberries $meal: dinner Eggplant with Chili Sauce After Sorting: $dinner: 0 Braised Bamboo Fungus $dinner: 1 Lemon Chicken $dinner: 2 Sweet Corn and Asparagus $meal: 0 Cashew Nuts and White Mushrooms $meal: 1 Dried Mulberries $meal: 2 Eggplant with Chili Sauce $meal: 3 Walnut Bun
Both arrays have been rearranged in ascending order by element value.
The first value in $dinner
is now
Braised
Bamboo
Fungus
, and the first value in
$meal
is Cashew
Nuts
and
White
Mushrooms
. The keys in
$dinner
haven’t changed because
it was a numeric array before we sorted it. The keys in
$meal
, however, have been replaced by numbers from
0
to 3
.
To sort an associative array by element value, use
asort()
. This
keeps keys together with their values. Example 4-25
shows the $meal
array from Example 4-24 sorted with asort()
.
Example 4-25. Sorting with asort()
$meal
=
array
(
'breakfast'
=>
'Walnut Bun'
,
'lunch'
=>
'Cashew Nuts and White Mushrooms'
,
'snack'
=>
'Dried Mulberries'
,
'dinner'
=>
'Eggplant with Chili Sauce'
);
"Before Sorting:
\n
"
;
foreach
(
$meal
as
$key
=>
$value
)
{
"
\$
meal:
$key
$value\n
"
;
}
asort
(
$meal
);
"After Sorting:
\n
"
;
foreach
(
$meal
as
$key
=>
$value
)
{
"
\$
meal:
$key
$value\n
"
;
}
Example 4-25 prints:
Before Sorting: $meal: breakfast Walnut Bun $meal: lunch Cashew Nuts and White Mushrooms $meal: snack Dried Mulberries $meal: dinner Eggplant with Chili Sauce After Sorting: $meal: lunch Cashew Nuts and White Mushrooms $meal: snack Dried Mulberries $meal: dinner Eggplant with Chili Sauce $meal: breakfast Walnut Bun
The values are sorted in the same way with asort()
as with sort()
, but this time, the
keys stick around.
While sort()
and asort()
sort
arrays by element value, you can also sort arrays by key with
ksort()
. This keeps key/value pairs together, but orders them by
key. Example 4-26 shows $meal
sorted with ksort()
.
Example 4-26. Sorting with ksort()
$meal
=
array
(
'breakfast'
=>
'Walnut Bun'
,
'lunch'
=>
'Cashew Nuts and White Mushrooms'
,
'snack'
=>
'Dried Mulberries'
,
'dinner'
=>
'Eggplant with Chili Sauce'
);
"Before Sorting:
\n
"
;
foreach
(
$meal
as
$key
=>
$value
)
{
"
\$
meal:
$key
$value\n
"
;
}
ksort
(
$meal
);
"After Sorting:
\n
"
;
foreach
(
$meal
as
$key
=>
$value
)
{
"
\$
meal:
$key
$value\n
"
;
}
Example 4-26 prints:
Before Sorting: $meal: breakfast Walnut Bun $meal: lunch Cashew Nuts and White Mushrooms $meal: snack Dried Mulberries $meal: dinner Eggplant with Chili Sauce After Sorting: $meal: breakfast Walnut Bun $meal: dinner Eggplant with Chili Sauce $meal: lunch Cashew Nuts and White Mushrooms $meal: snack Dried Mulberries
The array is reordered so the keys are now in ascending alphabetical
order. Each element is unchanged, so the value that went with each
key before the sorting is still attached to the same key after the
sorting. If you sort a numeric array with ksort()
, then the elements are ordered so the keys are in
ascending numeric order. This is the same order you start out with
when you create a numeric array using array()
or
[]
.
The array-sorting functions sort()
,
asort()
, and ksort()
have
counterparts that sort in descending order. The
reverse-sorting functions are named rsort()
, arsort()
, and krsort()
. They work exactly the same as sort()
,
asort()
, and ksort()
, except
they sort the arrays so the largest (or alphabetically last) key or
value is first in the sorted array, and subsequent elements are
arranged in descending order. Example 4-27 shows
arsort()
in action.
Example 4-27. Sorting with arsort()
$meal
=
array
(
'breakfast'
=>
'Walnut Bun'
,
'lunch'
=>
'Cashew Nuts and White Mushrooms'
,
'snack'
=>
'Dried Mulberries'
,
'dinner'
=>
'Eggplant with Chili Sauce'
);
"Before Sorting:
\n
"
;
foreach
(
$meal
as
$key
=>
$value
)
{
"
\$
meal:
$key
$value\n
"
;
}
arsort
(
$meal
);
"After Sorting:
\n
"
;
foreach
(
$meal
as
$key
=>
$value
)
{
"
\$
meal:
$key
$value\n
"
;
}
Example 4-27 prints:
Before Sorting: $meal: breakfast Walnut Bun $meal: lunch Cashew Nuts and White Mushrooms $meal: snack Dried Mulberries $meal: dinner Eggplant with Chili Sauce After Sorting: $meal: breakfast Walnut Bun $meal: dinner Eggplant with Chili Sauce $meal: snack Dried Mulberries $meal: lunch Cashew Nuts and White Mushrooms
The arsort()
function keeps the association between key and value, just like asort()
, but puts the elements in the opposite order (by value). The element whose value begins with W
is now first, and the element whose value begins with C
is last.
Using Multidimensional Arrays
As mentioned in “Array Basics”, the value of an array
element can be another array. This is useful when you want to store
data that has a more complicated structure than just a key and a
single value. A standard key/value pair is fine for matching up a
meal name (such as breakfast
or
lunch
) with a single dish (such as
Walnut Bun
or
Chicken with Cashew Nuts
),
but what about when each meal consists of more than one dish? Then,
element values should be arrays, not strings.
Use the
array()
construct or the []
short array syntax to create arrays
that have more arrays as element values, as shown in Example 4-28.
Example 4-28. Creating multidimensional arrays with array() and []
$meals
=
array
(
'breakfast'
=>
[
'Walnut Bun'
,
'Coffee'
],
'lunch'
=>
[
'Cashew Nuts'
,
'White Mushrooms'
],
'snack'
=>
[
'Dried Mulberries'
,
'Salted Sesame Crab'
]);
$lunches
=
[
[
'Chicken'
,
'Eggplant'
,
'Rice'
],
[
'Beef'
,
'Scallions'
,
'Noodles'
],
[
'Eggplant'
,
'Tofu'
]
];
$flavors
=
array
(
'Japanese'
=>
array
(
'hot'
=>
'wasabi'
,
'salty'
=>
'soy sauce'
),
'Chinese'
=>
array
(
'hot'
=>
'mustard'
,
'pepper-salty'
=>
'prickly ash'
));
Access elements in these arrays of arrays by using more sets of square brackets to identify elements. Each set of square brackets goes one level into the entire array. Example 4-29 demonstrates how to access elements of the arrays defined in Example 4-28.
Example 4-29. Accessing multidimensional array elements
$meals
[
'lunch'
][
1
];
// White Mushrooms
$meals
[
'snack'
][
0
];
// Dried Mulberries
$lunches
[
0
][
0
];
// Chicken
$lunches
[
2
][
1
];
// Tofu
$flavors
[
'Japanese'
][
'salty'
];
// soy sauce
$flavors
[
'Chinese'
][
'hot'
];
// mustard
Each level of an array is called a dimension. Before
this section, all the arrays in this chapter have been
one-dimensional
arrays. They each have one level of keys. Arrays such as
$meals
, $lunches
, and
$flavors
, shown in Example 4-29,
are called multidimensional arrays because they
each have more than one dimension.
You can also create or modify multidimensional arrays with the square bracket syntax. Example 4-30 shows some multidimensional array manipulation.
Example 4-30. Manipulating multidimensional arrays
$prices
[
'dinner'
][
'Sweet Corn and Asparagus'
]
=
12.50
;
$prices
[
'lunch'
][
'Cashew Nuts and White Mushrooms'
]
=
4.95
;
$prices
[
'dinner'
][
'Braised Bamboo Fungus'
]
=
8.95
;
$prices
[
'dinner'
][
'total'
]
=
$prices
[
'dinner'
][
'Sweet Corn and Asparagus'
]
+
$prices
[
'dinner'
][
'Braised Bamboo Fungus'
];
$specials
[
0
][
0
]
=
'Chestnut Bun'
;
$specials
[
0
][
1
]
=
'Walnut Bun'
;
$specials
[
0
][
2
]
=
'Peanut Bun'
;
$specials
[
1
][
0
]
=
'Chestnut Salad'
;
$specials
[
1
][
1
]
=
'Walnut Salad'
;
// Leaving out the index adds it to the end of the array
// This creates $specials[1][2]
$specials
[
1
][]
=
'Peanut Salad'
;
To iterate through each dimension of a multidimensional array, use
nested foreach()
or
for()
loops. Example 4-31 uses
foreach()
to iterate through a multidimensional
associative array.
Example 4-31. Iterating through a multidimensional array with foreach()
$flavors
=
array
(
'Japanese'
=>
array
(
'hot'
=>
'wasabi'
,
'salty'
=>
'soy sauce'
),
'Chinese'
=>
array
(
'hot'
=>
'mustard'
,
'pepper-salty'
=>
'prickly ash'
));
// $culture is the key and $culture_flavors is the value (an array)
foreach
(
$flavors
as
$culture
=>
$culture_flavors
)
{
// $flavor is the key and $example is the value
foreach
(
$culture_flavors
as
$flavor
=>
$example
)
{
"A
$culture
$flavor
flavor is
$example
.
\n
"
;
}
}
Example 4-31 prints:
A Japanese hot flavor is wasabi. A Japanese salty flavor is soy sauce. A Chinese hot flavor is mustard. A Chinese pepper-salty flavor is prickly ash.
The first foreach()
loop in Example 4-31 iterates through the first dimension of
$flavors
. The keys stored in
$culture
are the strings
Japanese
and Chinese
, and the
values stored in $culture_flavors
are the arrays
that are the element values of this dimension. The next
foreach()
iterates over those element value
arrays, copying keys such as hot
and
salty
into $flavor
, and values
such as wasabi
and soy
sauce
into $example
. The code
block of the second foreach()
uses variables from
both foreach()
statements to print out a complete
message.
Just like nested foreach()
loops iterate through
a multidimensional associative array, nested
for()
loops iterate through a multidimensional numeric array, as shown in
Example 4-32.
Example 4-32. Iterating through a multidimensional array with for()
$specials
=
array
(
array
(
'Chestnut Bun'
,
'Walnut Bun'
,
'Peanut Bun'
),
array
(
'Chestnut Salad'
,
'Walnut Salad'
,
'Peanut Salad'
)
);
// $num_specials is 2: the number of elements in the first dimension of $specials
for
(
$i
=
0
,
$num_specials
=
count
(
$specials
);
$i
<
$num_specials
;
$i
++
)
{
// $num_sub is 3: the number of elements in each subarray
for
(
$m
=
0
,
$num_sub
=
count
(
$specials
[
$i
]);
$m
<
$num_sub
;
$m
++
)
{
"Element [
$i
][
$m
] is "
.
$specials
[
$i
][
$m
]
.
"
\n
"
;
}
}
Example 4-32 prints:
Element [0][0] is Chestnut Bun Element [0][1] is Walnut Bun Element [0][2] is Peanut Bun Element [1][0] is Chestnut Salad Element [1][1] is Walnut Salad Element [1][2] is Peanut Salad
In Example 4-32, the outer for()
loop iterates over the two elements of $specials
.
The inner for()
loop iterates over each element
of the subarrays that hold the different strings. In the
print
statement, $i
is the
index in the first dimension (the elements of
$specials
), and $m
is the index
in the second dimension (the subarray).
To
interpolate a value
from a multidimensional array into a double-quoted string or here
document, use the curly brace syntax from Example 4-20. Example 4-33 uses curly
braces for interpolation to produce the same output as Example 4-32. In fact, the only different line in Example 4-33 is the print
statement.
Example 4-33. Multidimensional array element value interpolation
$specials
=
array
(
array
(
'Chestnut Bun'
,
'Walnut Bun'
,
'Peanut Bun'
),
array
(
'Chestnut Salad'
,
'Walnut Salad'
,
'Peanut Salad'
)
);
// $num_specials is 2: the number of elements in the first dimension of $specials
for
(
$i
=
0
,
$num_specials
=
count
(
$specials
);
$i
<
$num_specials
;
$i
++
)
{
// $num_sub is 3: the number of elements in each subarray
for
(
$m
=
0
,
$num_sub
=
count
(
$specials
[
$i
]);
$m
<
$num_sub
;
$m
++
)
{
"Element [
$i
][
$m
] is
{
$specials
[
$i
][
$m
]
}
\n
"
;
}
}
Chapter Summary
- Understanding the components of an array: elements, keys, and values
-
Defining an array in your programs two ways: with
array()
and with the short array syntax - Adding elements to an array with square brackets
- Understanding the shortcuts PHP provides for arrays with numeric keys
- Counting the number of elements in an array
-
Visiting each element of an array with
foreach()
-
Alternating table row CSS class names with
foreach()
and an array of class names -
Modifying array element values inside a
foreach()
code block -
Visiting each element of a numeric array with
for()
-
Alternating table row CSS class names with
for()
and the modulus operator (%
) -
Understanding the order in which
foreach()
andfor()
visit array elements - Checking for an array element with a particular key
- Checking for an array element with a particular value
- Interpolating array element values in strings
- Removing an element from an array
-
Generating a string from an array with
implode()
-
Generating an array from a string with
explode()
-
Sorting an array with
sort()
,asort()
, orksort()
- Sorting an array in reverse
- Defining a multidimensional array
- Accessing individual elements of a multidimensional array
-
Visiting each element in a multidimensional array with
foreach()
orfor()
- Interpolating multidimensional array elements in a string
Exercises
-
According to the US Census Bureau, the 10 largest American cities (by population) in 2010 were as follows:
- New York, NY (8,175,133 people)
- Los Angeles, CA (3,792,621)
- Chicago, IL (2,695,598)
- Houston, TX (2,100,263)
- Philadelphia, PA (1,526,006)
- Phoenix, AZ (1,445,632)
- San Antonio, TX (1,327,407)
- San Diego, CA (1,307,402)
- Dallas, TX (1,197,816)
- San Jose, CA (945,942)
Define an array (or arrays) that holds this information about locations and populations. Print a table of locations and population information that includes the total population in all 10 cities.
- Modify your solution to the previous exercise so that the rows in the result table are ordered by population. Then modify your solution so that the rows are ordered by city name.
- Modify your solution to the first exercise so that the table also contains rows that hold state population totals for each state represented in the list of cities.
-
For each of the following kinds of information, state how you would store it in an array and then give sample code that creates such an array with a few elements. For example, for the first item, you might say, “An associative array whose key is the student’s name and whose value is an associative array of grade and ID number,” as in the following:
$students
=
[
'James D. McCawley'
=>
[
'grade'
=>
'A+'
,
'id'
=>
271231
],
'Buwei Yang Chao'
=>
[
'grade'
=>
'A'
,
'id'
=>
818211
]
];
- The grades and ID numbers of students in a class
- How many of each item in a store inventory are in stock
- School lunches for a week: the different parts of each meal (entrée, side dish, drink, etc.) and the cost for each day
- The names of people in your family
- The names, ages, and relationship to you of people in your family
1 Scalar describes data
that has a single value: a number, a piece of text, true
, or false
.
Complex data types such as arrays, which hold multiple values, are
not scalars.
Get Learning PHP now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.