You want handler functions to execute whenever you read and write object properties. This lets you write generalized code to handle property access in your class.
Use the experimental overload extension and write _ _get( ) and _ _set( ) methods to intercept property requests.
Property overloading allows you to seamlessly obscure from the user the actual location of your object's properties and the data structure you use to store them.
For example, the pc_user class shown in Example 7-1 stores variables in an array, $data.
require_once 'DB.php'; class pc_user { var $data = array(); function pc_user($user) { /* connect to database and load information on * the user named $user into $this->data */ $dsn = 'mysql://user:password@localhost/test'; $dbh = DB::connect($dsn); if (DB::isError($dbh)) { die ($dbh->getMessage()); } $user = $dbh->quote($user); $sql = "SELECT name,email,age,gender FROM users WHERE user LIKE '$user'"; if ($data = $dbh->getAssoc($sql)) { foreach($data as $key => $value) { $this->data[$key] = $value; } } } function __get($property_name, &$property_value) { if (isset($this->data[$property_name])) { $property_value = $this->data[$property_name]; return true; } return false; } function __set($property_name, $property_value) { $this->data[$property_name] = $property_value; return true; } }
Here's how to use the pc_user class:
overload('pc_user'); $user = new pc_user('johnwood'); $name = $user->name; // reads $user->data['name'] $user->email = 'jonathan@wopr.mil'; // sets $user->data['email']
The class constructor connects to the users table in the database and retrieves information about the user named $user. When you set data, _ _set( ) rewrites the element inside of $data. Likewise, use _ _get( ) to trap the call and return the correct array element.
Using an array as the alternate variable storage source doesn't provide many benefits over a nonoverloaded object, but this feature isn't restricted to simple arrays. For instance, you can make $this->email return the get_name( ) method of an email object. You can also avoid pulling all the user information from the database at once and request it on demand. Another alternative is to use a more persistent storage mechanism, such as files, shared memory, or a database to hold data.
Recipe 6.8 for information on storing objects in external sources; documentation on the overload extension at http://www.php.net/overload.
Copyright © 2003 O'Reilly & Associates. All rights reserved.