7.9.1 Problem
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.
7.9.2 Solution
Use the experimental overload extension and write _ _get( ) and _ _set( ) methods to
intercept property requests.
7.9.3 Discussion
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.
Example 7-1. pc_user class
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.