What Are Arrays?


The final variable type I'll introduce in this book is the array. Unlike strings and numbers (which are scalar variables, meaning they can store only a single value at a time), an array can hold multiple, separate pieces of information. An array is therefore like a list of values, each value being a string or a number or even another array.

Arrays are structured as a series of key-value pairs, where one pair is an item or element of that array. For each item in the list, there is a key (or index) associated with it. The resulting structure is not unlike a spreadsheet or database table (Table 2.2).

Table 2.2. The $artists array uses numbers for its keys.

Array Example 1: $artists

KEY

VALUE

0

Low

1

Aimee Mann

2

Ani DiFranco

3

Spiritualized

4

Air


PHP supports two kinds of arrays: indexed, which use numbers as the keys (as in Table 2.2), and associative, which use strings as keys (Table 2.3). As in most programming languages, with indexed arrays, your arrays will begin with the first index at 0, unless you specify the keys explicitly.

Table 2.3. The $states array uses strings (specifically the state abbreviation) for its keys.

Array Example 2: $states

KEY

VALUE

MD

Maryland

PA

Pennsylvania

IL

Illinois

MO

Missouri

IA

Iowa


As you can see, an array follows the same naming rules as any other variable. So offhand, you might not be able to tell that $var is an array as opposed to a string or number. The important syntactical difference has to do with accessing individual array elements.

To retrieve a specific value from an array, you refer to the array name first, followed by the key, in square brackets:

 echo $artists[2]; // Ani DiFranco echo $states['MD']; // Maryland 

You can see that the array keys are used like other values in PHP: numbers (e.g., 2) are never quoted, whereas strings (MD) must be.

Because arrays use a different syntax than other variables, printing them can be trickier. First, since an array can contain multiple values, you cannot simple code:

 echo "Here is my list of states:  $states."; 

Second, the keys in associative arrays complicate printing them. The following code will cause a parse error:

 echo "IL is the abbreviation for  $states['IL]."; 

Superglobal Arrays

PHP includes several predefined arrays by default. I am speaking of the superglobal variables: $_GET, $_POST, $_SESSION, $_REQUEST, $_SERVER, $_COOKIE, and so forth (added to PHP as of version 4.1).

The $_GET variable is where PHP stores all of the variables and values sent to a PHP script via the get method (presumably but not necessarily from an HTML form). $_POST stores all of the data sent to a PHP script from an HTML form that uses the post method. Both of thesealong with $_COOKIEare subsets of $_REQUEST, which you've been using.

The superglobals have two benefits over registered global variables (see the earlier sidebar "Registering Globals"). First, they are more secure because they are more precise (they indicate where the variable came from). Second, they are global in scope (hence the name), which will mean more to you after Chapter 3, "Creating Dynamic Web Sites." For this reason, I'll continue to directly use the superglobals for the remainder of the book. If you find the syntax of these variables to be confusing, you can use the shorthand technique at the top of your scripts as you have been: $name = $_POST['name'];


To work around this, wrap your array name and key in curly braces when your array uses strings for its keys:

 echo "IL is the abbreviation for  {$states['IL]}."; 

Numerically indexed arrays don't have this problem, though:

 echo "The artist with an index of 4 is   $artists[4]."; 

If arrays seem slightly familiar to you already, that's because you've already worked with a couple: $_SERVER and $_REQUEST (see the sidebar on "Superglobal Arrays"). To acquaint you with another array and how to print array values directly, a modified version of the basic handle_form.php page (refer to Script 2.3) will be created using the more specific $_POST array.

To use arrays

1.

Open handle_form.php (refer to Script 2.3) in your text editor.

2.

Change the assignment of the $name and $comments variables to (Script 2.6).

 $name = stripslashes($_POST  ['name]); $comments = stripslashes($_POST  ['comments]); 

Script 2.6. The superglobal variables, like $_POST here, are just one type of array you'll use in PHP.


In the previous version of this script, the values of $name and $comments were assigned by referring to the $_REQUEST array, which will work. But since these variables come from a form that uses the post method (see Script 2.1), $_POST would be a more exact, and therefore more secure, reference.

3.

Delete the line that creates the $email variable.

Previously a shorthand version of $_REQUEST['email'] was created as $email. Since this script will now refer to $_POST['email'] directly within an echo() statement, this line is no longer needed.

4.

Alter the echo() statement to directly print the $_POST['email'] value.

 echo "<p>Thank you, <b>$name</b>,  for the following comments:<br /> <tt>$comments</tt></p> <p>We will reply to you at <i>  {$_POST['email]}</i>.</p>\n"; 

Once you comprehend the concept of an array, you still need to master the syntax involved in printing it. When printing an array element that uses a string for its key, use the curly braces (as in {$_POST['email']} here) to avoid parse errors.

5.

Save the file, upload to your Web server, and test in your Web browser (Figure 2.14).

Figure 2.14. Using the superglobal variables won't affect the operation of your script, but it does make it more secure.


Tips

  • Because PHP is lax with its variable structures, an array can even use a combination of numbers and strings as its keys. The only important rule is that the keys of an array must each be unique.

  • The superglobals are new to PHP as of version 4.1. If you are using an earlier version of the language, use $HTTP_POST_VARS instead of $_POST and $HTTP_GET_VARS instead of $_GET.

  • In case you are the curious type, the parse error resulting from not using curly braces when printing arrays with string keys is daunting (Figure 2.15).

    Figure 2.15. The added complexity of the array syntax can easily lead to parse errors.



Creating arrays

In the previous example, I used a PHP-generated array, but there will frequently be times when you want to create your own. There are two primary ways to define your own array. First, you could add an element at a time to build one:

 $array[] = 'Tobias'; $array[] = 'Maeby'; $array['wife'] = 'Lindsay'; 

It's important to understand that if you specify a key and a value already exists indexed with that same key, the new value will overwrite the existing one. For example,

 $array['son'] = 'Buster'; $array['son'] = 'Michael'; $array[2] = 'apple'; $array[2] = 'orange'; 

Instead of adding one element at a time, you can use the array() function to build an entire array in one step:

 $states = array ('IA' => 'Iowa', 'MD' =>   'Maryland); 

This function can be used whether or not you explicitly set the key:

 $artists = array ('Ani DiFranco', 'Air',   'Wilco); 

Or, if you set the first numeric key value, the added values will be keyed incrementally thereafter:

 $days = array (1 => 'Sunday','Monday',   'Tuesday); echo $days[3]; // Tuesday 

Finally, if you want to create an array of sequential numbers, you can use the range() function:

 $ten = range (1, 10); 

Accessing arrays

You've already seen how to access individual array elements by key (e.g., $_POST ['email']). This works when you know exactly what the keys are or if you want to refer to only a single element. To access every array element, use the foreach loop:

 foreach ($array as $value) {    // Do something with $value. } 

The foreach loop will iterate through every element in $array, assigning each element's value to the $value variable. To access both the keys and values, use

 foreach ($array as $key => $value) {    echo "The array value at $key is      $value."; } 

Using arrays, I'll show how easy it is to make a set of form pull-down menus to select a date.

To create and access arrays

1.

Create a new PHP document in your text editor (Script 2.7).

 <!DOCTYPE html PUBLIC "-//W3C//  DTD XHTML 1.0 Transitional//EN "http://www.w3.org/TR/xhtml1/DTD/  xhtml1-transitional.dtd> <html xmlns="http://www.w3.org/1999/  xhtml xml:lang="en" lang="en"> <head>   <meta http-equiv="content-type"     content="text/html;    charset=iso-8859-1 />   <title>Calendar</title> </head> <body> <form action="calendar.php"   method="post> <?php # Script 2.7 - calendar.php 

Script 2.7. Arrays are used to dynamically create three pull-down menus (refer to Figure 2.16).


Figure 2.16. These pull-down menus were created using arrays and the foreach loop.


One particular thing to note here is that the HTML form tag is required to create the pull-downs. Since it doesn't matter where or when you embed PHP, I include the form tag before going into PHP.

2.

Create an array for the months.

 $months = array (1 => 'January',  'February, 'March', 'April',  'May, 'June', 'July', 'August',  'September, 'October',  'November, 'December'); 

This first array will use numbers for the keys, from 1 to 12. Since I specified the first key, the following values will be indexed incrementally.

3.

Create the arrays for the days of the month and the years.

 $days = range (1, 31); $years = range (2005, 2015); 

Using the range() function, I can easily make an array of numbers.

4.

Generate the months pull-down menu.

 echo '<select name="month">'; foreach ($months as $key => $value) {   echo "<option value=\"$key\">    $value</option>\n; } echo '</select>'; 

With the foreach loop I can quickly generate all of the HTML code for the month pull-down menu. Each execution of the loop will create a line of code like <option value="1">January</option>.

5.

Generate the days and years pull-down menus.

 echo '<select name="day">'; foreach ($days as $value) {   echo "<option value=\"$value\">    $value</option>\n; } echo '</select>'; echo '<select name="year">'; foreach ($years as $value) {   echo "<option value=\"$value\">    $value</option>\n; } echo '</select>'; 

Unlike the months example, both the day and year pull-down menus will use the same thing for both the option's value and label (a number). This is why I didn't need to specify keys when making these arrays.

6.

Close the PHP, the form tag, and the HTML page.

 ?> </form> </body> </html> 

7.

Save the file as calendar.php, upload to your Web server, and test in your Web browser (Figure 2.16).

8.

If desired, view the source code in your browser by choosing View > Source or View > Page Source (Figure 2.17).

Figure 2.17. Most of the source code was generated by just a few lines of PHP


Tips

  • To determine the number of elements in an array, use the count() or sizeof() function (the two are synonymous).

     $num = count($array); 

  • The range() function can also create an array of sequential letters as of PHP 4.1:

     $alphabet = range ('a', 'z'); 

  • An array's keys can be multiple-worded strings, such as first name or phone number.

  • The is_array() function confirms that a variable is of the array type.

  • You don't have to use the names $key and $value in your foreach loop, but those are logical choices (some programmers abbreviate them as $k and $v).

  • If you see an Invalid argument supplied for foreach() error message, that means you are trying to use a foreach loop on a variable that is not an array.


Multidimensional arrays

When first introducing arrays, I mentioned that an array's values could be any combination of numbers, strings, and even other arrays. This last optionan array consisting of other arrayscreates a multidimensional array.

Multidimensional arrays are much more common than you might expect (especially if you use the superglobals) but remarkably easy to work with. As an example, Table 2.3 displayed an array called $states, which would have been created by

 $states = array ('MD' => 'Maryland',   'IL => 'Illinois', ...); 

If you had another similar array for Canada

 $provinces = array ('QC' => 'Quebec',   'AB => 'Alberta', ...); 

then these two arrays could be combined into one multidimensional array like so:

 $abbr = array ('US' => $states, 'Canada'   => $provinces); 

Now, $abbr is a multidimensional array. To access the $states array, you refer to $abbr['US']. To access Maryland, use $abbr['US'][ 'MD']. Simply use the name of the multidimensional array, followed by the key of the first array in square brackets (this key would happen to be the name of the inner array), followed by the key of the second, inner array (also in square brackets). To print out one of these values, surround the whole construct in curly braces:

 echo "The US state whose abbreviation is   MD is {$abbr['US]['MD']}."; 

Of course, you can still access multidimensional arrays using the foreach loop, nesting one inside another if necessary.

In this next example, $_POST will be a multidimensional array as the HTML form will create an array for one set of inputs.

To use multidimensional arrays

1.

Create a new HTML document in your text editor (Script 2.8).

 <!DOCTYPE html PUBLIC "-//W3C//  DTD XHTML 1.0 Transitional//EN "http://www.w3.org/TR/xhtml1/DTD/  xhtml1-transitional.dtd> <html xmlns="http://www.w3.org/1999/  xhtml xml:lang="en" lang="en"> <head>   <meta http-equiv="content-type"    content="text/html;    charset=iso-8859-1 />   <title>Tell Us About Yourself</    title> </head> <body> <!-- Script 2.8 - about.html --> 

Script 2.8. This form has a series of check boxes the user can select. That particular input will create a $_POST['interests'] variable that is itself an array.


2.

Begin the HTML form.

 <form action="handle_about.php"  method="post>  <fieldset><legend>Enter your   information in the form   below:</legend>  <p><b>Name:</b> <input type="text"   name="name size="20"   maxlength="40 /></p> 

The form will send all its data to the handle_about.php script, using the post method. The first input is the user's name.

3.

Create a series of check boxes so that users can select their interests.

 <p><b>Interests:</b>   <input type="checkbox" name=    "interests[]" value=    "Music /> Music   <input type="checkbox" name=    "interests[]" value=    "Movies /> Movies   <input type="checkbox" name=    "interests[]" value=    "Books /> Books   <input type="checkbox" name=    "interests[]" value=    "Skiing /> Skiing   <input type="checkbox" name=    "interests[]" value=    "Napping /> Napping </p> 

The interests section of the form will give the user the option of selecting multiple choices. There are two naming schemes you could use for the various inputs in such a case: Either give them a name that matches their value (Music, Movies, etc.) or use an array. Here I've used interests[] as the name, which will, in the handling PHP script, create an array at $_POST['interests'] that stores all of the boxes the user checked.

4.

Complete the page.

   </fieldset>   <div align="center"><input type=    "submit name="submit" value=    "Submit My Information /></div> </form> </body> </html> 

5.

Save the file as about.html.

Now I'll create handle_about.php to make use of the $_POST['interests'] multidimensional array.

To handle the form

1.

Create a new PHP document in your text editor (Script 2.9).

 <!DOCTYPE html PUBLIC "-//W3C//  DTD XHTML 1.0 Transitional//EN "http://www.w3.org/TR/xhtml1/DTD/  xhtml1-transitional.dtd> <html xmlns="http://www.w3.org/1999/  xhtml xml:lang="en" lang="en"> <head>   <meta http-equiv="content-type"    ontent="text/html;    harset=iso-8859-1 />   <title>About You Form Feedback</    itle> </head> <body> <?php # Script 2.9 - handle_about.php 

Script 2.9. This script prints out the values of $_POST['interests'], which is part of the multidimensional $_POST array.


2.

Validate that a name was entered.

 if (!empty($_POST['name'])) {   $name = stripslashes($_POST    ['name]); } else {   $name = NULL;   echo '<p><font color="red">You    forgot to enter your name!</    font></p>'; } 

The code here is almost exactly like that in earlier scripts (refer to Script 2.5), although it now uses the $_POST superglobal, which is more specific than $_REQUEST.

3.

Add the lines for validating the interests.

 if (isset($_POST['interests'])) {   $interests = TRUE; } else {   $interests = NULL;   echo '<p><font color="red">You    forgot to enter your    interests!</font></p>'; } 

This conditional validates that $_POST ['interests'] has a value. If so, $interests is set to TRUE. Otherwise, $interests is set to NULL and an error message is printed.

4.

Begin the final conditional.

 if ($name && $interests) {   echo "Thank you, <b>$name</b>. You    entered your interests as:<ul>"; 

If the form was filled out properly, both $name and $interests will have values, making this condition true. In that case, the user's name is printed as part of a message. Next, the submitted interests will be reprinted. Because I want the interests to be displayed as an HTML list, I print the initial unordered list tag (<ul>) here.

5.

Print out all the selected interests.

 foreach ($_POST['interests'] as  $value) {   echo "<li>$value</li>\n"; } 

Following the syntax outlined earlier, this loop will access every element of $_POST['interests']. Due to the nature of form check boxes, only those boxes that were selected will have a value in the $_POST['interests'] array. Within the loop itself each value is printed within HTML list tags.

6.

Complete the final conditional.

   echo '</ul>'; } else {   echo '<p><font color="red">Please    go back and fill out the form    again.</font></p>'; } 

The first echo() statement closes the HTML list. The second is printed if either $name or $interests does not have a value, meaning that the form wasn't properly filled out.

7.

Complete the PHP and HTML.

 ?> </body> </html> 

8.

Save the file as handle_about.php, upload to your Web server along with about.html, and test both in your Web browser (Figures 2.18, 2.19, and 2.20).

Figure 2.18. This HTML form makes use of check boxes.


Figure 2.19. The selected interests are repeated back to the user as an HTML list.


Figure 2.20. If a name was not entered or no interests were selected, error messages are generated.


Tips

  • Even if the user selects only one interest, $_POST['interests'] will still be an array because the HTML name for the corresponding input is interests[] (the square brackets make it an array).

  • You can also end up with a multidimensional array by having an HTML form's select menu allow for multiple selections:

     <select name="interests[]" multiple="multiple">   <option value="Music">Music</    option>   <option value="Movies">Movies</    option>   <option value="Books">Books</    option>   <option value="Skiing">Skiing</    option>   <option value="Napping">Napping</    option> </select> 


Arrays and strings

Because these two variable types are so commonly used, PHP has two functions for converting between strings and arrays.

 $array = explode (separator, $string); $string = implode (glue, $array); 

The key to using and understanding these two functions is the separator and glue relationships. When turning an array into a string, you set the gluethe characters or code that will be inserted between the array values in the generated string. Conversely, when turning a string into an array, you specify the separator, which is the code that delineates between the different elements in the generated array.

 $string1 = 'Mon - Tue - Wed - Thur - Fri'; $days_array = explode (' - ', $string1); 

The $days_array variable is now a five-element array, with Mon indexed at 0, Tue indexed at 1, etc.

 $string2 = implode (', ', $days_array); 

The $string2 variable is now a comma- separated list of days: Mon, Tue, Wed, Thurs, Fri.

To convert an array to a string

1.

Open handle_about.php (refer to Script 2.9) in your text editor.

2.

Replace the definition of the $interests variable with (Script 2.10)

 $interests = implode (', ', $_POST  ['interests]); 

Script 2.10. The implode() function greatly facilitates conversions between arrays and strings.


Instead of setting $interests to be equal to trUE, it'll now be a string of comma-separated values.

3.

Remove the foreach loop and the echo() statement from the main conditional.

Since $interests is now an easily printable string, I'll do away with the loop and the use of the HTML list.

4.

Change the first main conditional echo() statement to read

 echo "Thank you, <b>$name</b>.  You entered your interests  as:<br />$interests; 

5.

Save the file as handle_about.php, upload to your Web server, and test in your Web browser (Figure 2.21).

Figure 2.21. Although this script works more or less the same as it had before (see Figure 2.20), the code is shorter and easier to comprehend (refer to Script 2.10).


Tips

  • The function join() is a synonym for implode().

  • For some reason I have an impossible time remembering when to use explode() and when to use implode(). As a mnemonic device, I try to remember that explode() blows things (a string) into little bits (an array).

  • The explode() function takes a third, optional parameter, which is a number limiting how many array elements are created.


Sorting arrays

One of the many advantages arrays have over the other variable types is the ability to sort them. PHP includes several functions you can use for sorting arrays, all simple in syntax:

 $names = array ('George Michael', 'Ann',   'Buster); sort($names); 

The sorting functions perform three kinds of sorts. First, you can sort an array by value, discarding the original keys, using sort(). It's important to understand that the array's keys will be reset after the sorting process, so if the key-value relationship is important, you should not use this function.

Second, you can sort an array by value while maintaining the keys, using asort(). Third, you can sort an array by key, using ksort(). Each of these can sort in reverse order if you change them to rsort(), arsort(), and krsort() respectively.

To demonstrate the effect sorting arrays will have, I'll create an array of movie titles and ratings (how much I liked them on a scale of 1 to 10) and then display this list in different ways.

To sort arrays

1.

Create a new PHP document in your text editor (Script 2.11).

 <!DOCTYPE html PUBLIC "-//W3C//  DTD XHTML 1.0 Transitional//EN "http://www.w3.org/TR/xhtml1/DTD/  xhtml1-transitional.dtd> <html xmlns="http://www.w3.org/1999/  xhtml xml:lang="en" lang="en"> <head>   <meta http-equiv="content-type"    content="text/html;    charset=iso-8859-1 />   <title>Sorting Arrays</title> </head> <body> <?php # Script 2.11 - sorting.php 

Script 2.11. Arrays can be sorted in numerous ways.


2.

Create a new array.

 $movies = array ( 10 => 'Casablanca', 9 => 'To Kill a Mockingbird', 2 => 'The English Patient', 8 => 'Sideways', 7 => 'Donnie Darko' ); 

This array uses movie titles as the values and their respective ratings as their key. This structure will open up several possibilities for sorting the whole list. Feel free to change the movie listings and rankings as you see fit (just don't chastise me for my taste in films).

3.

Print out the array as is.

 echo '<p>In their original order:  <br /><pre>Rating Title '; foreach ($movies as $key => $value) {   echo "$key\t$value\n"; } echo '</pre></p>'; 

At this point in the script, the array is in the order it was created. To verify this, I'll print it out. I'm using the pre tags (for preformatted) to create a simple table in the resulting HTML. Within the foreach loop, the key is printed, followed by a tab, followed by the value, and then a newline.

4.

Sort the array alphabetically by title and print it again.

 echo '<p>Sorted by title:<br />  <pre>Rating Title '; asort($movies); foreach ($movies as $key => $value) {   echo "$key\t$value\n"; } echo '</pre></p>'; 

The asort() function sorts an array by value while maintaining the key-value relationship. The rest of the code is a repetition of Step 3.

5.

Sort the array numerically by descending rating and print again.

 echo '<p>Sorted by rating:<br />  <pre>Rating Title '; krsort($movies); foreach ($movies as $key => $value) {   echo "$key\t$value\n"; } echo '</pre></p>'; 

The ksort() function will sort an array by key, but in ascending order. Since I want that reversed (highest score first), I use krsort(). This function, like asort(), maintains the key-value relationships.

6.

Complete the PHP and HTML.

 ?> </body> </html> 

7.

Save the file as sorting.php, upload to your Web server, and test in your Web browser (Figure 2.22).

Figure 2.22. This page demonstrates the different ways arrays can be sorted.


Tips

  • If you want to use decimal ratings for the movies, the rating numbers must be quoted or else PHP would drop the decimal points (numeric keys are always integers).

  • To randomize the order of an array, use shuffle().

  • PHP's natsort() function can be used to sort arrays in a more natural order (primarily handling numbers in strings better).

  • PHP can also sort arrays using a user-defined sorting function. See the PHP manual for more information on the usort() function.

  • PHP will sort arrays as if they were in English by default. If you need to sort an array in another language, use PHP's setlocale() function to change the language setting.

  • Technically the <pre> tag is not allowed in XHTML Transitional documents, but I wanted to save you having to create all the requisite table HTML.




    PHP and MySQL for Dynamic Web Sites. Visual QuickPro Guide
    PHP and MySQL for Dynamic Web Sites: Visual QuickPro Guide (2nd Edition)
    ISBN: 0321336577
    EAN: 2147483647
    Year: 2005
    Pages: 166
    Authors: Larry Ullman

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net