Tuesday, July 14, 2009

Beginning PHP and Oracle From Novice to Professional by W. Jason Gilmore and Bob Bryla Chapter 5

Much of your time as a programmer is spent working with data sets. Some examples of data sets include the names of all employees at a corporation; the U.S. presidents and their corresponding
birth dates; and the years between 1900 and 1975. In fact, working with data sets is so prevalent that a means for managing these groups within code is a common feature of all mainstream program- ming languages. Within the PHP language, this feature is known as the array, which offers an ideal way to store, manipulate, sort, and retrieve data sets.
This chapter introduces arrays and the language’s impressive variety of functions used to work with them. Specifically you’ll learn how to do the following:

• Create arrays

• Output arrays

• Test for an array

• Add and remove array elements

• Locate array elements

• Traverse arrays

• Determine array size and element uniqueness

• Sort arrays

• Merge, slice, splice, and dissect arrays

Before beginning the overview of these functions, let’s take a moment to formally define an array and review some fundamental concepts on how PHP regards this important datatype.

What Is an Array?

An array is traditionally defined as a group of items that share certain characteristics, such as simi- larity (car models, baseball teams, types of fruit, etc.) and type (e.g., all strings or integers). Each item is distinguished by a special identifier known as a key. PHP takes this definition a step further, forgoing the requirement that the items share the same datatype. For example, an array could quite possibly contain items such as state names, ZIP codes, exam scores, or playing card suits.
Each item consists of two components: the aforementioned key and a value. The key serves as the lookup facility for retrieving its counterpart, the value. Keys can be numerical or associative. Numerical keys bear no real relation to the value other than the value’s position in the array. As an example, the array could consist of an alphabetically sorted list of state names, with key 0 representing Alabama, and key 49 representing Wyoming. Using PHP syntax, this might look like the following:

91

$states = array(0 => "Alabama", "1" => "Alaska"..."49" => "Wyoming");

Using numerical indexing, you could reference the first state (Alabama) like so:

$states[0]

■Note Like many programming languages, PHP’s numerically indexed arrays begin with position 0, not 1.

An associative key logically bears a direct relation to its corresponding value. Mapping arrays associatively is particularly convenient when using numerical index values just doesn’t make sense. For instance, you might want to create an array that maps state abbreviations to their names, like this: OH/Ohio, PA/Pennsylvania, and NY/New York. Using PHP syntax, this might look like the following:

$states = array("OH" => "Ohio", "PA" => "Pennsylvania", "NY" => "New York")

You could then reference Ohio like this:

$states["OH"]

It’s also possible to create arrays of arrays, known as multidimensional arrays. For example, you could use a multidimensional array to store U.S. state information. Using PHP syntax, it might look like this:

$states = array (
"Ohio" => array("population" => "11,353,140", "capital" => "Columbus"), "Nebraska" => array("population" => "1,711,263", "capital" => "Omaha")
);

You could then reference Ohio’s population:

$states["Ohio"]["population"]

This would return the following :

11,353,140

Logically you’ll require a means for traversing arrays. As you’ll learn throughout this chapter, PHP offers many ways to do so. Regardless of whether you’re using associative or numerical keys, keep in mind that all rely on the use of a central feature known as an array pointer. The array pointer acts like a bookmark, telling you the position of the array that you’re presently examining. You won’t work with the array pointer directly, but instead will traverse the array using either built-in language features or functions. Still, it’s useful to understand this basic concept.

Creating an Array

Unlike other languages, PHP doesn’t require that you assign a size to an array at creation time. In fact, because it’s a loosely typed language, PHP doesn’t even require that you declare the array before using it, although you’re free to do so. Each approach is introduced in this section, beginning with the informal variety.

Individual elements of a PHP array are referenced by denoting the element between a pair of square brackets. Because there is no size limitation on the array, you can create the array simply by making reference to it, like this:

$state[0] = "Delaware";

You can then display the first element of the array $state like this:

echo $state[0];

Additional values can be added by mapping each new value to an array index, like this:

$state[1] = "Pennsylvania";
$state[2] = "New Jersey";
...
$state[49] = "Hawaii";

Interestingly, if you intend for the the index value to be numerical and ascending, you can omit the index value at creation time:
$state[] = "Pennsylvania";
$state[] = "New Jersey";
...
$state[] = "Hawaii";

Creating associative arrays in this fashion is equally trivial except that the key is always required. The following example creates an array that matches U.S. state names with their date of entry into the Union:

$state["Delaware"] = "December 7, 1787";
$state["Pennsylvania"] = "December 12, 1787";
$state["New Jersey"] = "December 18, 1787";
...
$state["Hawaii"] = "August 21, 1959";

The array() construct, discussed next, is a functionally identical yet somewhat more formal means for creating arrays.

Creating Arrays with array()

The array() construct takes as its input zero or more items and returns an array consisting of these input elements. Its prototype looks like this:

array array([item1 [,item2 ... [,itemN]]])

Here is an example of using array() to create an indexed array:

$languages = array("English", "Gaelic", "Spanish");
// $languages[0] = "English", $languages[1] = "Gaelic", $languages[2] = "Spanish"

You can also use array() to create an associative array, like this:

$languages = array("Spain" => "Spanish", "Ireland" => "Gaelic",
"United States" => "English");
// $languages["Spain"] = "Spanish"
// $languages["Ireland"] = "Gaelic"
// $languages["United States"] = "English"

Extracting Arrays with list()

The list() construct is similar to array(), though it’s used to make simultaneous variable assign- ments from values extracted from an array in just one operation. Its prototype looks like this:

void list(mixed...)

This construct can be particularly useful when you’re extracting information from a database or file. For example, suppose you wanted to format and output information read from a text file named users.txt. Each line of the file contains user information, including name, occupation, and favorite color with each item delimited by a vertical bar. A typical line would look similar to the following:

Nino Sanzi|professional golfer|green

Using list(), a simple loop could read each line, assign each piece of data to a variable, and format and display the data as needed. Here’s how you could use list() to make multiple variable assignments simultaneously:

// Open the users.txt file
$users = fopen("users.txt", "r");

// While the EOF hasn't been reached, get next line while ($line = fgets($users, 4096)) {

// use explode() to separate each piece of data. list($name, $occupation, $color) = explode("|", $line);

// format and output the data printf("Name: %s <br />", $name); printf("Occupation: %s <br />", $occupation); printf("Favorite color: %s <br />", $color);

}
fclose($users);

Each line of the users.txt file will be read and formatted similarly to this:

Name: Nino Sanzi
Occupation: professional golfer
Favorite Color: green

Reviewing the example, list() depends on the function explode() to split each line into three elements, which explode() does by using the vertical bar as the element delimiter. (The explode() function is formally introduced in Chapter 9.) These elements are then assigned to $name, $occupation, and $color. At that point, it’s just a matter of formatting for display to the browser.

Populating Arrays with a Predefined Value Range

The range() function provides an easy way to quickly create and fill an array consisting of a range of low and high integer values. An array containing all integer values in this range is returned. Its proto- type looks like this:

array range(int low, int high [, int step])

For example, suppose you need an array consisting of all possible face values of a die:

$die = range(0,6);
// Same as specifying $die = array(0,1,2,3,4,5,6)

But what if you want a range consisting of solely even or odd values? Or a range consisting of values solely divisible by five? The optional step parameter offers a convenient means for doing so. For example, if you want to create an array consisting of all even values between 0 and 20, you could use a step value of 2:

$even = range(0,20,2);
// $even = array(0,2,4,6,8,10,12,14,16,18,20);

The range() function can also be used for character sequences. For example, suppose you want to create an array consisting of the letters A through F:

$letters = range("A","F");
// $letters = array("A,","B","C","D","E","F");

PRINTING ARRAYS FOR TESTING PURPOSES

So far the array contents in the previous examples have been displayed using comments. While this works great for instructional purposes, in the real world you’ll need to know how to easily output their contents to the screen for testing purposes. This is most commonly done with the print_r() function. Its prototype follows:

boolean print_r(mixed variable [, boolean return])

The print_r() function accepts a variable and sends its contents to standard output, returning TRUE on success and FALSE otherwise. This in itself isn’t particularly exciting, until you realize it will organize an array’s contents (as well as an object’s) into a readable format. For example, suppose you want to view the contents of an associative array consisting of states and their corresponding state capitals. You could call print_r() like this:

print_r($states);

This returns the following:

Array ( [Ohio] => Columbus [Iowa] => Des Moines [Arizona] => Phoenix )

The optional parameter return modifies the function’s behavior, causing it to return the output to the caller, rather than send it to standard output. Therefore, if you want to return the contents of the preceding $states array, you just set return to TRUE:

$stateCapitals = print_r($states, TRUE);

This function is used repeatedly throughout this chapter as a simple means for displaying example results. Keep in mind the print_r() function isn’t the only way to output an array, but rather offers a convenient
means for doing so. You’re free to output arrays using a looping conditional, such as while or for; in fact, using
these sorts of loops is required to implement many application features. We’ll return to this method repeatedly throughout this and later chapters.

Testing for an Array

When you incorporate arrays into your application, you’ll sometimes need to know whether a particular variable is an array. A built-in function, is_array(), is available for accomplishing this task. Its prototype follows:

boolean is_array(mixed variable)

The is_array() function determines whether variable is an array, returning TRUE if it is and FALSE otherwise. Note that even an array consisting of a single value will still be considered an array. An example follows:

$states = array("Florida");
$state = "Ohio";
printf("\$states is an array: %s <br />", (is_array($states) ? "TRUE" : "FALSE"));
printf("\$state is an array: %s <br />", (is_array($state) ? "TRUE" : "FALSE"));

Executing this example produces the following:

$states is an array: TRUE
$state is an array: FALSE

Adding and Removing Array Elements

PHP provides a number of functions for both growing and shrinking an array. Some of these functions are provided as a convenience to programmers who wish to mimic various queue implementations (FIFO, LIFO, etc.), as reflected by their names (push, pop, shift, and unshift). This section intro- duces these functions and offers several examples.

■Note A traditional queue is a data structure in which the elements are removed in the same order in which they
were entered, known as first-in-first-out, or FIFO. In contrast, a stack is a data structure in which the elements are removed in the order opposite to that in which they were entered, known as last-in-first-out, or LIFO.

Adding a Value to the Front of an Array

The array_unshift() function adds elements onto the front of the array. All preexisting numerical keys are modified to reflect their new position in the array, but associative keys aren’t affected. Its prototype follows:

int array_unshift(array array, mixed variable [, mixed variable...])

The following example adds two states to the front of the $states array:

$states = array("Ohio","New York");
array_unshift($states,"California","Texas");
// $states = array("California","Texas","Ohio","New York");

Adding a Value onto the End of an Array

The array_push() function adds a value onto the end of an array, returning TRUE on success and FALSE otherwise. You can push multiple variables onto the array simultaneously by passing these variables into the function as input parameters. Its prototype follows:

int array_push(array array, mixed variable [, mixed variable...])

The following example adds two more states onto the $states array:

$states = array("Ohio","New York");
array_push($states,"California","Texas");
// $states = array("Ohio","New York","California","Texas");

Removing a Value from the Front of an Array

The array_shift() function removes and returns the item found in an array. Resultingly, if numer- ical keys are used, all corresponding values will be shifted down, whereas arrays using associative keys will not be affected. Its prototype follows:

mixed array_shift(array array)

The following example removes the first state from the $states array:

$states = array("Ohio","New York","California","Texas");
$state = array_shift($states);
// $states = array("New York","California","Texas")
// $state = "Ohio"

Removing a Value from the End of an Array

The array_pop() function removes and returns the last element from an array. Its prototype follows:

mixed array_pop(array target_array)

The following example removes the last state from the $states array:

$states = array("Ohio","New York","California","Texas");
$state = array_pop($states);
// $states = array("Ohio", "New York", "California"
// $state = "Texas"

Locating Array Elements

The ability to efficiently sift through data is absolutely crucial in today’s information-driven society. This section introduces several functions that enable you to search arrays in order to locate items of interest.

Searching an Array

The in_array() function searches an array for a specific value, returning TRUE if the value is found, and FALSE otherwise. Its prototype follows:

boolean in_array(mixed needle, array haystack [, boolean strict])

In the following example, a message is output if a specified state (Ohio) is found in an array consisting of states having statewide smoking bans:

$state = "Ohio";
$states = array("California", "Hawaii", "Ohio", "New York");
if(in_array($state, $states)) echo "Not to worry, $state is smoke-free!";

The optional third parameter, strict, forces in_array() to also consider type.

Searching Associative Array Keys

The function array_key_exists() returns TRUE if a specified key is found in an array, and returns
FALSE otherwise. Its prototype follows:

boolean array_key_exists(mixed key, array array)

The following example will search an array’s keys for Ohio, and if found, will output information about its entrance into the Union:

$state["Delaware"] = "December 7, 1787";
$state["Pennsylvania"] = "December 12, 1787";
$state["Ohio"] = "March 1, 1803";
if (array_key_exists("Ohio", $state))
printf("Ohio joined the Union on %s", $state["Ohio"]);

The following is the result:

Ohio joined the Union on March 1, 1803

Searching Associative Array Values

The array_search() function searches an array for a specified value, returning its key if located, and
FALSE otherwise. Its prototype follows:

mixed array_search(mixed needle, array haystack [, boolean strict])

The following example searches $state for a particular date (December 7), returning informa- tion about the corresponding state if located:

$state["Ohio"] = "March 1";
$state["Delaware"] = "December 7";
$state["Pennsylvania"] = "December 12";
$founded = array_search("December 7", $state);
if ($founded) printf("%s was founded on %s.", $founded, $state[$founded]);

The output follows:

Delaware was founded on December 7.

Retrieving Array Keys

The array_keys() function returns an array consisting of all keys located in an array. Its prototype follows:

array array_keys(array array [, mixed search_value])

If the optional search_value parameter is included, only keys matching that value will be returned. The following example outputs all of the key values found in the $state array:

$state["Delaware"] = "December 7, 1787";
$state["Pennsylvania"] = "December 12, 1787";
$state["New Jersey"] = "December 18, 1787";
$keys = array_keys($state);
print_r($keys);

The output follows:

Array ( [0] => Delaware [1] => Pennsylvania [2] => New Jersey )

Retrieving Array Values

The array_values() function returns all values located in an array, automatically providing numeric indexes for the returned array. Its prototype follows:

array array_values(array array)

The following example will retrieve the population numbers for all of the states found in
$population:

$population = array("Ohio" => "11,421,267", "Iowa" => "2,936,760");
print_r(array_values($population));

This example will output the following:

Array ( [0] => 11,421,267 [1] => 2,936,760 )

Traversing Arrays

The need to travel across an array and retrieve various keys, values, or both is common, so it’s not a surprise that PHP offers numerous functions suited to this need. Many of these functions do double duty: retrieving the key or value residing at the current pointer location, and moving the pointer to the next appropriate location. These functions are introduced in this section.

Retrieving the Current Array Key

The key() function returns the key located at the current pointer position of input_array. Its proto- type follows:

mixed key(array array)

The following example will output the $capitals array keys by iterating over the array and moving the pointer:
$capitals = array("Ohio" => "Columbus", "Iowa" => "Des Moines"); echo "<p>Can you name the capitals of these states?</p>"; while($key = key($capitals)) {
printf("%s <br />", $key);
next($capitals);
}

This returns the following:

Can You name the capitals of these states?

Ohio
Iowa

Note that key() does not advance the pointer with each call. Rather, you use the next() func- tion, whose sole purpose is to accomplish this task. This function is introduced later in this section.

Retrieving the Current Array Value

The current() function returns the array value residing at the current pointer position of the array. Its prototype follows:

mixed current(array array)

Let’s revise the previous example, this time retrieving the array values:

$capitals = array("Ohio" => "Columbus", "Iowa" => "Des Moines");

echo "<p>Can you name the states belonging to these capitals?</p>";

while($capital = current($capitals)) { printf("%s <br />", $capital); next($capitals);
}

The output follows:

Can you name the states belonging to these capitals?

Columbus
Des Moines

Retrieving the Current Array Key and Value

The each() function returns the current key/value pair from the array and advances the pointer one position. Its prototype follows:

array each(array array)

The returned array consists of four keys, with keys 0 and key containing the key name, and keys
1 and value containing the corresponding data. If the pointer is residing at the end of the array before executing each(), FALSE is returned.

Moving the Array Pointer

Several functions are available for moving the array pointer. These functions are introduced in this section.

Moving the Pointer to the Next Array Position

The next() function returns the array value residing at the position immediately following that of the current array pointer. Its prototype follows:

mixed next(array array)

An example follows:

$fruits = array("apple", "orange", "banana");
$fruit = next($fruits); // returns "orange"
$fruit = next($fruits); // returns "banana"

You can also move the pointer backward, as well as directly to the beginning and conclusion of the array. These capabilities are introduced next.

Moving the Pointer to the Previous Array Position

The prev() function returns the array value residing at the location preceding the current pointer location, or FALSE if the pointer resides at the first position in the array. Its prototype follows:

mixed prev(array array)

Because prev() works in exactly the same fashion as next(), no example is necessary.

Moving the Pointer to the First Array Position

The reset() function serves to set an array pointer back to the beginning of the array. Its prototype follows:

mixed reset(array array)

This function is commonly used when you need to review or manipulate an array multiple times within a script, or when sorting has completed.

Moving the Pointer to the Last Array Position

The end() function moves the pointer to the last position of an array, returning the last element. Its prototype follows:

mixed end(array array)

The following example demonstrates retrieving the first and last array values:

$fruits = array("apple", "orange", "banana");
$fruit = current($fruits); // returns "apple"
$fruit = end($fruits); // returns "banana"

Passing Array Values to a Function

The array_walk() function will pass each element of an array to the user-defined function. This is useful when you need to perform a particular action based on each array element. If you intend to actually modify the array key/value pairs, you’ll need to pass each key/value to the function as a reference. Its prototype follows:

boolean array_walk(array &array, callback function [, mixed userdata])

The user-defined function must take two parameters as input. The first represents the array’s current value, and the second represents the current key. If the optional userdata parameter is present in the call to array_walk(), its value will be passed as a third parameter to the user-defined function.
You are probably scratching your head, wondering how this function could possibly be of any use. Perhaps one of the most effective examples involves the sanity-checking of user-supplied form data. Suppose the user is asked to provide six keywords that he thinks best describe the state in which he lives. A sample form is provided in Listing 5-1.

Listing 5-1. Using an Array in a Form

<form action="submitdata.php" method="post">
<p>
Provide up to six keywords that you believe best describe the state in which you live:
</p>
<p>Keyword 1:<br />
<input type="text" name="keyword[]" size="20" maxlength="20" value="" /></p>
<p>Keyword 2:<br />
<input type="text" name="keyword[]" size="20" maxlength="20" value="" /></p>
<p>Keyword 3:<br />
<input type="text" name="keyword[]" size="20" maxlength="20" value="" /></p>
<p>Keyword 4:<br />
<input type="text" name="keyword[]" size="20" maxlength="20" value="" /></p>
<p>Keyword 5:<br />
<input type="text" name="keyword[]" size="20" maxlength="20" value="" /></p>
<p>Keyword 6:<br />
<input type="text" name="keyword[]" size="20" maxlength="20" value="" /></p>
<p><input type="submit" value="Submit!"></p>
</form>

This form information is then sent to some script, referred to as submitdata.php in the form. This script should sanitize user data then insert it into a database for later review. Using array_walk(), you can easily filter the keywords using a predefined function:

<?php
function sanitize_data(&$value, $key) {
$value = strip_tags($value);
}

array_walk($_POST['keyword'],"sanitize_data");
?>

The result is that each value in the array is run through the strip_tags() function, which results
in any HTML and PHP tags being deleted from the value. Of course, additional input checking would be necessary, but this should suffice to illustrate the utility of array_walk().

■Note If you’re not familiar with PHP’s form-handling capabilities, see Chapter 13.

Determining Array Size and Uniqueness

A few functions are available for determining the number of total and unique array values. These functions are introduced in this section.

Determining the Size of an Array

The count() function returns the total number of values found in an array. Its prototype follows:

integer count(array array [, int mode])

If the optional mode parameter is enabled (set to 1), the array will be counted recursively, a feature useful when counting all elements of a multidimensional array. The first example counts the total number of vegetables found in the $garden array:
$garden = array("cabbage", "peppers", "turnips", "carrots");
echo count($garden);

This returns the following:

4

The next example counts both the scalar values and array values found in $locations:

$locations = array("Italy","Amsterdam",array("Boston","Des Moines"),"Miami");
echo count($locations,1);

This returns the following:

6

You may be scratching your head at this outcome because there appears to be only five elements in the array. The array entity holding Boston and Des Moines is counted as an item, just as its contents are.

■Note The sizeof() function is an alias of count(). It is functionally identical.

Counting Array Value Frequency

The array_count_values() function returns an array consisting of associative key/value pairs. Its prototype follows:

array array_count_values(array array)

Each key represents a value found in the input_array, and its corresponding value denotes the frequency of that key’s appearance (as a value) in the input_array. An example follows:
$states = array("Ohio","Iowa","Arizona","Iowa","Ohio");
$stateFrequency = array_count_values($states);
print_r($stateFrequency);

This returns the following:

Array ( [Ohio] => 2 [Iowa] => 2 [Arizona] => 1 )

Determining Unique Array Values

The array_unique() function removes all duplicate values found in an array, returning an array consisting of solely unique values. Its prototype follows:

array array_unique(array array)

An example follows:

$states = array("Ohio","Iowa","Arizona","Iowa","Ohio");
$uniqueStates = array_unique($states);
print_r($uniqueStates);

This returns the following:

Array ( [0] => Ohio [1] => Iowa [2] => Arizona )

Sorting Arrays

To be sure, data sorting is a central topic of computer science. Anybody who’s taken an entry-level programming class is well aware of sorting algorithms such as bubble, heap, shell, and quick. This subject rears its head so often during daily programming tasks that the process of sorting data is
as common as creating an if conditional or a while loop. PHP facilitates the process by offering a
multitude of useful functions capable of sorting arrays in a variety of manners. Those functions are introduced in this section.

■Tip By default, PHP’s sorting functions sort in accordance with the rules as specified by the English language.
If you need to sort in another language, say French or German, you’ll need to modify this default behavior by setting your locale using the setlocale() function.

Reversing Array Element Order

The array_reverse() function reverses an array’s element order. Its prototype follows:

array array_reverse(array array [, boolean preserve_keys])

If the optional preserve_keys parameter is set to TRUE, the key mappings are maintained. Other- wise, each newly rearranged value will assume the key of the value previously presiding at that position:
$states = array("Delaware","Pennsylvania","New Jersey");
print_r(array_reverse($states));
// Array ( [0] => New Jersey [1] => Pennsylvania [2] => Delaware )

Contrast this behavior with that resulting from enabling preserve_keys:

$states = array("Delaware","Pennsylvania","New Jersey");
print_r(array_reverse($states,1));
// Array ( [2] => New Jersey [1] => Pennsylvania [0] => Delaware )

Arrays with associative keys are not affected by preserve_keys; key mappings are always preserved in this case.

Flipping Array Keys and Values

The array_flip() function reverses the roles of the keys and their corresponding values in an array. Its prototype follows:

array array_flip(array array)

An example follows:

$state = array("Delaware","Pennsylvania","New Jersey");
$state = array_flip($state);
print_r($state);

This example returns the following:

Array ( [Delaware] => 0 [Pennsylvania] => 1 [New Jersey] => 2 )

Sorting an Array

The sort() function sorts an array, ordering elements from lowest to highest value. Its prototype follows:

void sort(array array [, int sort_flags])

The sort() function doesn’t return the sorted array. Instead, it sorts the array “in place,” returning nothing, regardless of outcome. The optional sort_flags parameter modifies the function’s default behavior in accordance with its assigned value:

SORT_NUMERIC: Sorts items numerically. This is useful when sorting integers or floats.

SORT_REGULAR: Sorts items by their ASCII value. This means that B will come before a, for instance. A quick ssearch online produces several ASCII tables, so one isn’t reproduced in this book.

SORT_STRING: Sorts items in a fashion that might better correspond with how a human might perceive the correct order. See natsort() for further information about this matter, introduced later in this section.

Consider an example. Suppose you want to sort exam grades from lowest to highest:

$grades = array(42,98,100,100,43,12);
sort($grades);
print_r($grades);

The outcome looks like this:

Array ( [0] => 12 [1] => 42 [2] => 43 [3] => 98 [4] => 100 [5] => 100 )

It’s important to note that key/value associations are not maintained. Consider the following example:

$states = array("OH" => "Ohio", "CA" => "California", "MD" => "Maryland");
sort($states);
print_r($states);

Here’s the output:

Array ( [0] => California [1] => Maryland [2] => Ohio )

To maintain these associations, use asort(), introduced next.

Sorting an Array While Maintaining Key/Value Pairs

The asort() function is identical to sort(), sorting an array in ascending order, except that the key/value correspondence is maintained. Its prototype follows:

void asort(array array [,integer sort_flags])

Consider an array that contains the states in the order in which they joined the Union:

$state[0] = "Delaware";
$state[1] = "Pennsylvania";
$state[2] = "New Jersey";

Sorting this array using sort() causes the associative correlation to be lost, which is probably a bad idea. Sorting using sort() produces the following ordering:

Array ( [0] => Delaware [1] => New Jersey [2] => Pennsylvania )

However, sorting with asort() produces the following:

Array ( [0] => Delaware [2] => New Jersey [1] => Pennsylvania )

If you use the optional sort_flags parameter, the exact sorting behavior is determined by its value, as described in the sort() section.

Sorting an Array in Reverse Order

The rsort() function is identical to sort(), except that it sorts array items in reverse (descending)
order. Its prototype follows:

void rsort(array array [, int sort_flags])

An example follows:

$states = array("Ohio","Florida","Massachusetts","Montana");
sort($states);
print_r($states);

It returns the following:

Array ( [0] => Ohio [1] => Montana [2] => Massachusetts [3] => Florida )

If the optional sort_flags parameter is included, the exact sorting behavior is determined by its value, as explained in the sort() section.

Sorting an Array in Reverse Order While Maintaining Key/Value Pairs

Like asort(), arsort() maintains key/value correlation. However, it sorts the array in reverse order. Its prototype follows:

void arsort(array array [, int sort_flags])

An example follows:

$states = array("Delaware","Pennsylvania","New Jersey");
arsort($states);
print_r($states);

It returns the following:

Array ( [1] => Pennsylvania [2] => New Jersey [0] => Delaware )

If the optional sort_flags parameter is included, the exact sorting behavior is determined by its value, as described in the sort() section.

Sorting an Array Naturally

The natsort() function is intended to offer a sorting mechanism comparable to the mechanisms that people normally use. Its prototype follows:

void natsort(array array)

The PHP manual offers an excellent example, shown here, of what it means to sort an array “naturally.” Consider the following items: picture1.jpg, picture2.jpg, picture10.jpg, picture20.jpg. Sorting these items using typical algorithms results in the following ordering:

picture1.jpg, picture10.jpg, picture2.jpg, picture20.jpg

Certainly not what you might have expected, right? The natsort() function resolves this dilemma, sorting the array in the order you would expect, like so:

picture1.jpg, picture2.jpg, picture10.jpg, picture20.jpg

Case-Insensitive Natural Sorting

The function natcasesort() is functionally identical to natsort(), except that it is case insensitive:

void natcasesort(array array)

Returning to the file-sorting dilemma raised in the natsort() section, suppose that the pictures are named like this: Picture1.JPG, picture2.jpg, PICTURE10.jpg, picture20.jpg. The natsort() function would do its best, sorting these items like so:

PICTURE10.jpg, Picture1.JPG, picture2.jpg, picture20.jpg

The natcasesort() function resolves this idiosyncrasy, sorting as you might expect:

Picture1.jpg, PICTURE10.jpg, picture2.jpg, picture20.jpg

Sorting an Array by Key Values

The ksort() function sorts an array by its keys, returning TRUE on success and FALSE otherwise. Its prototype follows:

integer ksort(array array [, int sort_flags])

If the optional sort_flags parameter is included, the exact sorting behavior is determined by its value, as described in the sort() section. Keep in mind that the behavior will be applied to key sorting but not to value sorting.

Sorting Array Keys in Reverse Order

The krsort() function operates identically to ksort(), sorting by key, except that it sorts in reverse
(descending) order. Its prototype follows:

integer krsort(array array [, int sort_flags])

Sorting According to User-Defined Criteria

The usort() function offers a means for sorting an array by using a user-defined comparison algo- rithm, embodied within a function. This is useful when you need to sort data in a fashion not offered by one of PHP’s built-in sorting functions. Its prototype follows:

void usort(array array, callback function_name)

The user-defined function must take as input two arguments and must return a negative integer, zero, or a positive integer, respectively, based on whether the first argument is less than, equal to, or greater than the second argument. Not surprisingly, this function must be made available to the same scope in which usort() is being called.
A particularly applicable example of where usort() comes in handy involves the ordering of
American-format dates (month, day, year, as opposed to day, month, year used by most other coun- tries). Suppose that you want to sort an array of dates in ascending order. While you might think the sort() or natsort() functions are suitable for the job, as it turns out, both produce undesirable results. The only recourse is to create a custom function capable of sorting these dates in the correct ordering:
<?php
$dates = array('10-10-2003', '2-17-2002', '2-16-2003',
'1-01-2005', '10-10-2004');
sort($dates);

echo "<p>Sorting the array using the sort() function:</p>";
print_r($dates);

natsort($dates);

echo "<p>Sorting the array using the natsort() function: </p>";
print_r($dates);

function DateSort($a, $b) {

// If the dates are equal, do nothing. if($a == $b) return 0;

// Disassemble dates
list($amonth, $aday, $ayear) = explode('-',$a);
list($bmonth, $bday, $byear) = explode('-',$b);

// Pad the month with a leading zero if leading number not present
$amonth = str_pad($amonth, 2, "0", STR_PAD_LEFT);
$bmonth = str_pad($bmonth, 2, "0", STR_PAD_LEFT);

// Pad the day with a leading zero if leading number not present
$aday = str_pad($aday, 2, "0", STR_PAD_LEFT);
$bday = str_pad($bday, 2, "0", STR_PAD_LEFT);

// Reassemble dates
$a = $ayear . $amonth . $aday;
$b = $byear . $bmonth . $bday;

// Determine whether date $a > $date b return ($a > $b) ? 1 : -1;
}

usort($dates, 'DateSort');

echo "<p>Sorting the array using the user-defined DateSort() function: </p>";

print_r($dates);
?>

This returns the following (formatted for readability):

Sorting the array using the sort() function:
Array ( [0] => 1-01-2005 [1] => 10-10-2003 [2] => 10-10-2004 [3] => 2-16-2003 [4] => 2-17-2002 )

Sorting the array using the natsort() function:
Array ( [0] => 1-01-2005 [3] => 2-16-2003 [4] => 2-17-2002 [1] => 10-10-2003 [2] => 10-10-2004 )

Sorting the array using the user-defined DateSort() function: Array ( [0] => 2-17-2002 [1] => 2-16-2003 [2] => 10-10-2003
[3] => 10-10-2004 [4] => 1-01-2005 )

Merging, Slicing, Splicing, and Dissecting Arrays This section introduces a number of functions that are capable of performing somewhat more complex array-manipulation tasks, such as combining and merging multiple arrays, extracting a cross-section of
array elements, and comparing arrays.

Merging Arrays

The array_merge() function merges arrays together, returning a single, unified array. The resulting array will begin with the first input array parameter, appending each subsequent array parameter in the order of appearance. Its prototype follows:

array array_merge(array array1, array array2 [..., array arrayN])

If an input array contains a string key that already exists in the resulting array, that key/value pair will overwrite the previously existing entry. This behavior does not hold true for numerical keys, in which case the key/value pair will be appended to the array. An example follows:
$face = array("J","Q","K","A");
$numbered = array("2","3","4","5","6","7","8","9");
$cards = array_merge($face, $numbered);
shuffle($cards);
print_r($cards);
This returns something along the lines of the following (your results will vary because of the shuffle):

Array ( [0] => 8 [1] => 6 [2] => K [3] => Q [4] => 9 [5] => 5
[6] => 3 [7] => 2 [8] => 7 [9] => 4 [10] => A [11] => J )

Recursively Appending Arrays

The array_merge_recursive() function operates identically to array_merge(), joining two or more arrays together to form a single, unified array. The difference between the two functions lies in the way that this function behaves when a string key located in one of the input arrays already exists within the resulting array. array_merge() will simply overwrite the preexisting key/value pair, replacing it with the one found in the current input array. array_merge_recursive() will instead merge the values together, forming a new array with the preexisting key as its name. Its prototype follows:

array array_merge_recursive(array array1, array array2 [, arrayN...])

An example follows:

$class1 = array("John" => 100, "James" => 85);
$class2 = array("Micky" => 78, "John" => 45);
$classScores = array_merge_recursive($class1, $class2);
print_r($classScores);

This returns the following:

Array ( [John] => Array ( [0] => 100 [1] => 45 ) [James] => 85 [Micky] => 78 )

Note that the key John now points to a numerically indexed array consisting of two scores.

Combining Two Arrays

The array_combine() function produces a new array consisting of a submitted set of keys and corre- sponding values. Its prototype follows:

array array_combine(array keys, array values)

Both input arrays must be of equal size, and neither can be empty. An example follows:

$abbreviations = array("AL","AK","AZ","AR");
$states = array("Alabama","Alaska","Arizona","Arkansas");
$stateMap = array_combine($abbreviations,$states);
print_r($stateMap);

This returns the following:

Array ( [AL] => Alabama [AK] => Alaska [AZ] => Arizona [AR] => Arkansas )

Slicing an Array

The array_slice() function returns a section of an array based on a provided starting and ending
offset value. Its prototype follows:

array array_slice(array array, int offset [, int length])

A positive offset value will cause the slice to begin offset positions from the beginning of the array, while a negative offset value will start the slice offset positions from the end of the array. If the optional length parameter is omitted, the slice will start at offset and end at the last element of the array. If length is provided and is positive, it will end at offset + length positions from the beginning of the array. Conversely, if length is provided and is negative, it will end at count(input_array) – length positions from the end of the array. Consider an example:

$states = array("Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut");

$subset = array_slice($states, 4);

print_r($subset);

This returns the following:

Array ( [0] => California [1] => Colorado [2] => Connecticut )

Consider a second example, this one involving a negative length:

$states = array("Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut");

$subset = array_slice($states, 2, -2);

print_r($subset);

This returns the following:

Array ( [0] => Arizona [1] => Arkansas [2] => California )

Splicing an Array

The array_splice() function removes all elements of an array found within a specified range, returning those removed elements in the form of an array. Its prototype follows:

array array_splice(array array, int offset [, int length [, array replacement]])

A positive offset value will cause the splice to begin that many positions from the beginning of the array, while a negative offset will start the splice that many positions from the end of the array. If the optional length parameter is omitted, all elements from the offset position to the conclusion of the array will be removed. If length is provided and is positive, the splice will end at offset + length posi- tions from the beginning of the array. Conversely, if length is provided and is negative, the splice will end at count(input_array) – length positions from the end of the array. An example follows:

$states = array("Alabama", "Alaska", "Arizona", "Arkansas", "California", "Connecticut");

$subset = array_splice($states, 4);

print_r($states);

print_r($subset);

This produces the following (formatted for readability):

Array ( [0] => Alabama [1] => Alaska [2] => Arizona [3] => Arkansas ) Array ( [0] => California [1] => Connecticut )

You can use the optional parameter replacement to specify an array that will replace the target segment. An example follows:

$states = array("Alabama", "Alaska", "Arizona", "Arkansas", "California", "Connecticut");

$subset = array_splice($states, 2, -1, array("New York", "Florida"));

print_r($states);

This returns the following:

Array ( [0] => Alabama [1] => Alaska [2] => New York
[3] => Florida [4] => Connecticut )

Calculating an Array Intersection

The array_intersect() function returns a key-preserved array consisting only of those values present in the first array that are also present in each of the other input arrays. Its prototype follows:

array array_intersect(array array1, array array2 [, arrayN...])

The following example will return all states found in the $array1 that also appear in $array2
and $array3:

$array1 = array("OH","CA","NY","HI","CT");
$array2 = array("OH","CA","HI","NY","IA");
$array3 = array("TX","MD","NE","OH","HI");
$intersection = array_intersect($array1, $array2, $array3);
print_r($intersection);

This returns the following:

Array ( [0] => OH [3] => HI )

Note that array_intersect() considers two items to be equal only if they also share the same datatype.

Calculating Associative Array Intersections

The function array_intersect_assoc() operates identically to array_intersect(), except that it also considers array keys in the comparison. Therefore, only key/value pairs located in the first array that are also found in all other input arrays will be returned in the resulting array. Its prototype follows:

array array_intersect(array array1, array array2 [, arrayN...])

The following example returns an array consisting of all key/value pairs found in $array1 that also appear in $array2 and $array3:

$array1 = array("OH" => "Ohio", "CA" => "California", "HI" => "Hawaii");
$array2 = array("50" => "Hawaii", "CA" => "California", "OH" => "Ohio");
$array3 = array("TX" => "Texas", "MD" => "Maryland", "OH" => "Ohio");
$intersection = array_intersect_assoc($array1, $array2, $array3);
print_r($intersection);

This returns the following:

Array ( [OH] => Ohio )

Note that Hawaii was not returned because the corresponding key in $array2 is 50 rather than
HI (as is the case in the other two arrays).

Calculating Array Differences

Essentially the opposite of array_intersect(), the function array_diff() returns those values located in the first array that are not located in any of the subseqeuent arrays:

array array_diff(array array1, array array2 [, arrayN...])

An example follows:

$array1 = array("OH","CA","NY","HI","CT");
$array2 = array("OH","CA","HI","NY","IA");
$array3 = array("TX","MD","NE","OH","HI");
$diff = array_diff($array1, $array2, $array3);
print_r($intersection);

This returns the following:

Array ( [0] => CT )

Calculating Associative Array Differences

The function array_diff_assoc() operates identically to array_diff(), except that it also considers array keys in the comparison. Therefore only key/value pairs located in the first array but not appearing in any of the other input arrays will be returned in the result array. Its prototype follows:

array array_diff_assoc(array array1, array array2 [, arrayN...])

The following example only returns "HI" => "Hawaii" because this particular key/value appears in $array1 but doesn’t appear in $array2 or $array3:

$array1 = array("OH" => "Ohio", "CA" => "California", "HI" => "Hawaii");
$array2 = array("50" => "Hawaii", "CA" => "California", "OH" => "Ohio");
$array3 = array("TX" => "Texas", "MD" => "Maryland", "KS" => "Kansas");
$diff = array_diff_assoc($array1, $array2, $array3);
print_r($diff);

This returns the following:

Array ( [HI] => Hawaii )

Other Useful Array Functions

This section introduces a number of array functions that perhaps don’t easily fall into one of the prior sections but are nonetheless quite useful.

Returning a Random Set of Keys

The array_rand() function will return a random number of keys found in an array. Its prototype follows:

mixed array_rand(array array [, int num_entries])

If you omit the optional num_entries parameter, only one random value will be returned. You can tweak the number of returned random values by setting num_entries accordingly. An example follows:
$states = array("Ohio" => "Columbus", "Iowa" => "Des Moines", "Arizona" => "Phoenix");
$randomStates = array_rand($states, 2);
print_r($randomStates);

This returns the following (your output may vary):

Array ( [0] => Arizona [1] => Ohio )

Shuffling Array Elements

The shuffle() function randomly reorders an array. Its prototype follows:

void shuffle(array input_array)

Consider an array containing values representing playing cards:

$cards = array("jh","js","jd","jc","qh","qs","qd","qc", "kh","ks","kd","kc","ah","as","ad","ac");
// shuffle the cards
shuffle($cards);
print_r($positions);
This returns something along the lines of the following (your results will vary because of the shuffle):

Array ( [0] => js [1] => ks [2] => kh [3] => jd
[4] => ad [5] => qd [6] => qc [7] => ah
[8] => kc [9] => qh [10] => kd [11] => as
[12] => ac [13] => jc [14] => jh [15] => qs )

Adding Array Values

The array_sum() function adds all the values of input_array together, returning the final sum. Its prototype follows:

mixed array_sum(array array)

If other datatypes (a string, for example) are found in the array, they will be ignored. An example follows:

<?php
$grades = array(42,"hello",42);
$total = array_sum($grades);
print $total;
?>

This returns the following:

84

Subdividing an Array

The array_chunk() function breaks input_array into a multidimensional array that includes several smaller arrays consisting of size elements. Its prototype follows:

array array_chunk(array array, int size [, boolean preserve_keys])

If the input_array can’t be evenly divided by size, the last array will consist of fewer than size elements. Enabling the optional parameter preserve_keys will preserve each value’s corresponding key. Omitting or disabling this parameter results in numerical indexing starting from zero for each array. An example follows:

$cards = array("jh","js","jd","jc","qh","qs","qd","qc", "kh","ks","kd","kc","ah","as","ad","ac");

// shuffle the cards shuffle($cards);

// Use array_chunk() to divide the cards into four equal "hands"
$hands = array_chunk($cards, 4);

print_r($hands);

This returns the following (your results will vary because of the shuffle):

Array ( [0] => Array ( [0] => jc [1] => ks [2] => js [3] => qd )
[1] => Array ( [0] => kh [1] => qh [2] => jd [3] => kd ) [2] => Array ( [0] => jh [1] => kc [2] => ac [3] => as ) [3] => Array ( [0] => ad [1] => ah [2] => qc [3] => qs ) )

Summary

Arrays play an indispensable role in programming and are ubiquitous in every imaginable type of application, Web-based or not. The purpose of this chapter was to bring you up to speed regarding many of the PHP functions that will make your programming life much easier as you deal with these arrays.
The next chapter focuses on yet another very important topic: object-oriented programming. This topic has a particularly special role in PHP 5 because the process was entirely redesigned for this major release.

0 comments: