Book HomePHP CookbookSearch this book

7.9. Using Property Overloading

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.

For example, the pc_user class shown in Example 7-1 stores variables in an array, $data.

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.

7.9.4. See Also

Recipe 6.8 for information on storing objects in external sources; documentation on the overload extension at http://www.php.net/overload.



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.