Необходимо, чтобы функции обработчики выполнялись при каждом чтении или записи свойств объекта. Это позволяет написать универсальный код для управления доступом к свойствам класса.
Это делается при помощи экспериментального расширения перегрузки; кроме того, надо написать методы __get() и __set() для перехвата запросов свойств.
Перегрузка свойств позволяет без труда скрыть от пользователя истинное расположение свойств объекта и структуру данных, в которой
они хранятся.
Например, класс pc_user, приведенный в примере описанном ниже, хранит переменные в массиве $data.
Пример pc_user class
require_once 'DB.php';
class pc_user {
var $data = array();
function pc_user($user) {
/* соединяемся с базой данных и загружаем информацию
* о пользователе по имени $user в $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;
}
}
Ниже показано, как использовать класс pc_user:
overload('pc_user');
$user = new pc_user('johnwood');
$name = $user -> name; // читает $user -> data['name']
$user -> email = 'jonathan@wopr.mil'; // устанавливает $user -> data['email']
Конструктор класса подсоединяется к таблице users в базе данных и извлекает информацию о пользователе по имени $user. При установке
данных функция __set() переписывает элементы массива $data. Аналогично применяется функция __get(), чтобы перехватить вызов и возвратить правильный элемент массива.
Использование массива в качестве альтернативного исходного хранилища переменных не дает большого преимущества перед объектом без
перегрузки, но эта функциональность не ограничена простыми массивами. Например, можно заставить $this -> email вернуть метод get_name()
объекта email. Можно также избежать извлечения всей информации
о пользователе за один раз и запрашивать ее по мере необходимости.
Другой альтернативой является использование более устойчивого механизма хранения данных, такого как файлы, разделяемая память
или база данных.
Документацию по расширению перегрузки на http://www.php.net/overload.