Lesson Weekend

The arrays we just covered are called numerically indexed arrays, because you can access each element using a number called an index, like $my_array[2]. You can use them to make things like shopping lists, lists of people to invite to a party, or lists of words. But what if we don't just want a list of words, we want a list of definitions that can be looked up by their word? Or what if we don't just want a list of people, but a list of phone numbers that can be looked up by a person's name?

For this type of situation, there is another kind of array called an associative array, which we are going to start using now. Type this into the PHP shell:

> $dictionary = array("apple" => "a fruit, commonly red or green", "zebra" => "an animal with black and white stripes", "computer" => "that big shiny box you are using right now");
> echo $dictionary["zebra"];
an animal with black and white stripes
> echo $dictionary["computer"];
that big shiny box you are using right now
> echo $dictionary["apple"];
a fruit, commonly red or green

Here we have created an array using the array function like normal, but inside the parenthesis we use a special character => to associate three words with their definitions. Remember how we could enter the index number into square brackets [ ] to get a value out of a normal, numerically indexed array? Now we can use a word to do the same thing, so you don't need to remember the order of the items in your list.

Let's look at another example. What if we are ordering a bunch of different flavors of cupcake for an office party? We will need an associative array to keep track of the number of cakes we want to order of each kind.

> $cupcake_order = array("vanilla" => 12, "chocolate" => 24, "raspberry" => 6, "caramel apple" => 36);

This would actually be really confusing if we tried to store these numbers of cupcakes to order in the more basic, numerically indexed array. If the numbers were just listed in order without tying them to words to represent flavors, it would be easy to mix them up and get 36 vanilla cupcakes instead of 12. Now when we get to the bakery we can easily check how many of each type we need:

> echo $cupcake_order["vanilla"]; // How many vanilla cupcakes do we want?
12
> echo $cupcake_order["chocolate"]; // How many chocolate?
24
> echo $cupcake_order["raspberry"]; 
6
> echo $cupcake_order["caramel apple"];
36

You know how we type $_GET["name_of_input_field"] and it returns the value the user entered into that input field? Does that look familiar? That's because the built-in variable $_GET is an associative array, just like our dictionary and cupcake orders above.

Let's add a few more words to our dictionary. We can use the square brackets for that too:

> $dictionary["cat"] = "a small furry creature that people worship on the internet";
> $dictionary["chocolate"] = "only the best food ever";
> print_r($dictionary);
Array
(
    [apple] => a fruit, commonly red or green
    [zebra] => an animal with black and white stripes
    [computer] => that big shiny box you're using right now
    [cat] => a small furry creature that people worship on the internet
    [chocolate] => only the best food ever
)

You can see that both "cat" and "chocolate" have been added to the array with their definitions.

We can also overwrite the values of existing entries:

> $dictionary["cat"] = "a small domesticated carnivorous mammal";
> echo $dictionary["cat"];
a small domesticated carnivorous mammal
> var_dump($dictionary);
Array
(
    [apple] => a fruit, commonly red or green
    [zebra] => an animal with black and white stripes
    [computer] => that big shiny box you're using right now
    [cat] => a small domesticated carnivorous mammal
    [chocolate] => only the best food ever
)

Each word like "cat" or "zebra" on the left of the => symbol is called a key. The information stored with that key on the right of the => is called a value. In the above example, "cat" is a key, and "a small furry creature that people worship on the internet" is its value. Similarly, "chocolate" is a key, and "only the best food ever" is its value. People often say that an associative array stores key-value pairs.

To explore how to use associative arrays in a web page, let's create an address book website which allows the user to input up to 5 names and addresses. First, we'll need a form. Let's call this address_book_form.html and save it in your document root.

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <title>Make an Address Book</title>
</head>
<body>
    <div class="container">
        <h1>Let's make you an address book.</h1>
        <form action="address_book.php">
            <div class="form-group">
                <label for="person1_name">Name: </label>
                <input id="person1_name" name="person1_name" class="form-control" type="text">
            </div>
            <div class="form-group">
                <label for="person1_address">Address: </label>
                <input id="person1_address" name="person1_address" class="form-control" type="text">
            </div>
            <div class="form-group">
                <label for="person2_name">Name: </label>
                <input id="person2_name" name="person2_name" class="form-control" type="text">
            </div>
            <div class="form-group">
                <label for="person2_address">Address: </label>
                <input id="person2_address" name="person2_address" class="form-control" type="text">
            </div>
            <div class="form-group">
                <label for="person3_name">Name: </label>
                <input id="person3_name" name="person3_name" class="form-control" type="text">
            </div>
            <div class="form-group">
                <label for="person3_address">Address: </label>
                <input id="person3_address" name="person3_address" class="form-control" type="text">
            </div>
            <div class="form-group">
                <label for="person4_name">Name: </label>
                <input id="person4_name" name="person4_name" class="form-control" type="text">
            </div>
            <div class="form-group">
                <label for="person4_address">Address: </label>
                <input id="person4_address" name="person4_address" class="form-control" type="text">
            </div>
            <div class="form-group">
                <label for="person5_name">Name: </label>
                <input id="person5_name" name="person5_name" class="form-control" type="text">
            </div>
            <div class="form-group">
                <label for="person5_address">Address: </label>
                <input id="person5_address" name="person5_address" class="form-control" type="text">
            </div>
            <button class="btn-info" type="submit">Create</button>
        </form>
    </div>
</body>
</html>

This will call the file address_book.php in your document root, so go ahead and create that file next. It should take each name and address from our form and put them into an associative array as a key-value pair. Then we're going to use a foreach loop, just like in the last lesson, to print all of the names and addresses into our browser.

<?php 
    $person1_name = $_GET["person1_name"];
    $person2_name = $_GET["person2_name"];
    $person3_name = $_GET["person3_name"];
    $person4_name = $_GET["person4_name"];
    $person5_name = $_GET["person5_name"];
    $person1_address = $_GET["person1_address"];
    $person2_address = $_GET["person2_address"];
    $person3_address = $_GET["person3_address"];
    $person4_address = $_GET["person4_address"];
    $person5_address = $_GET["person5_address"];
    $address_book[$person1_name] = $person1_address;
    $address_book[$person2_name] = $person2_address;
    $address_book[$person3_name] = $person3_address;
    $address_book[$person4_name] = $person4_address;
    $address_book[$person5_name] = $person5_address;
?>
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <title>Address Book</title>
</head>
<body>
    <div class="container">
        <h1>Address Book</h1>
        <ul>
          <?php 
              foreach ($address_book as $name => $address) {
                  echo "<li>" . "$name: $address" . "</li>";
              }
          ?>
        </ul>
    </div>
</body>
</html>

First, we create 10 variables to hold the names and addresses from our form. Then, we use each name as a key to store the address as a value. Then, inside of the HTML under the <h1>, we create a foreach loop to directly print addresses into our browser.

When using a foreach loop with key-value pairs, it is almost the same as with a regular numerically indexed array. The only difference is that instead of picking one variable for each entry in the list, we pick a variable for both the key and the value. They go to the right of the as inside of the parenthesis, separated by the same => symbol that we used when creating an array using the array function.

For each entry in our address book, we call the key $name and the value $address. Then we use echo to print them both inside of a set of <li> tags.

Now what about removing things from associative arrays? Easy! Just use the unset function. It takes one argument - the key for the item you would like to remove from the array. Let's remove raspberry from our cupcake order in the PHP shell.

> $cupcake_order = array("vanilla" => 12, "chocolate" => 24, "raspberry" => 6, "caramel apple" => 36);  // The original cupcake order
> var_dump($cupcake_order);
array(4) {
  ["vanilla"]=>
  int(12)
  ["chocolate"]=>
  int(24)
  ["raspberry"]=>
  int(6)
  ["caramel apple"]=>
  int(36)
}
> unset($cupcake_order["raspberry"]);  // Remove raspberry cupcakes.
> var_dump($cupcake_order);  // Now it's just vanilla, chocolate and caramel apple.
array(3) {
  ["vanilla"]=>
  int(12)
  ["chocolate"]=>
  int(24)
  ["caramel apple"]=>
  int(36)
}

Now you have all the basic tools for working with collections of data.

Let's summarize the things we can do with the two kinds of arrays we have learned about in this lesson and the last.

  • Numerically indexed arrays: We can store a group of items in a particular order, and individual items can be set, edited or fetched by putting the item's index number into square brackets.
  • Associative arrays: Information is stored by using words as keys, instead of numbers counting from 0. Items in these arrays can be set, edited or fetched by putting the item's key into square brackets. Remember to use quotes around the key, because it's a string.
  • We can use foreach to loop through either kind of array.
  • We can add an item to to the end of a numerically indexed array using the array_push function. Since order doesn't matter for associative arrays, you can just use the square brackets method to add items to it.
  • To delete an item from a numerically indexed array, use array_splice. It takes 3 arguments: the array to modify, the index of the item to delete, and the number of items to delete, starting from this index.
  • To delete an item from an associative array, use the unset function. It takes 1 argument - the array you wish to modify with the key you wish to remove in square brackets next to it: unset($my_array["key"]);