CHAPTER 4 – Overloading the Array Access Syntax
4.2.2 Overloading the Array Access Syntax It is common to have key/value mappings or, in other words, lookup dictionar- ies in your application framework. For this purpose, PHP supports associa- tive arrays that map either integer or string values to any other PHP value. This feature was covered in Chapter 2, "PHP 5 Basic Language," and in case you forgot about it, here's an example that looks up the user John's social- security number using an associative array which holds this information: print "John's ID number is " . $userMap["John"]; Associative arrays are extremely convenient when you have all the infor- mation at hand. But consider a government office that has millions of people in its database; it just wouldn't make sense to load the entire database into the $userMap associative array just to look up one user. A possible alternative is to write a method that will look up the user's id number via a database call. The previous code would look something like the following: print "John's ID number is " . $db->FindIDNumber("John"); This example would work well, but many developers prefer the associa- tive array syntax to access key/value-like dictionaries. For this purpose, PHP 5 enables you to overload an object so that it can behave like an array. Basically, it would enable you to use the array syntax, but behind the scenes, a method written by you would be called, which would execute the relevant database call, returning the wanted value. It is really a matter of personal preference as to what method to use. Sometimes, it is nicer to use this overloading ability than the verbosity of call- ing a method, and it's up to you to decide which method suits you best. To allow your class to overload the array syntax, it needs to implement the ArrayAccess interface (see Figure 4.1). interface ArrayAccess bool offsetExists($index) mixed offsetGet($index) void offsetSet($index,$new_value) void offsetUnset($index) Fig. 4.1 ArrayAccess interface. The following example shows how to use it. It is incomplete because the database methods themselves aren't implemented: class UserToSocialSecurity implements ArrayAccess { private $db; // An object which includes database access methods function offsetExists($name) { return $this->db->userExists($name); } function offsetGet($name) { return $this->db->getUserId($name); } function offsetSet($name, $id) { $this->db->setUserId($name, $id); } function offsetUnset($name) { $this->db->removeUser($name); } } $userMap = new UserToSocialSecurity(); print "John's ID number is " . $userMap["John"]; You can see that the object $userMap is used just like an array, but behind the scenes, when the $userMap["John"] lookup is performed, the offsetGet() method is invoked, which in turn calls the database getUserId() method.