Перегрузка свойств

Задача
Необходимо, чтобы функции обработчики выполнялись при каждом чтении или записи свойств объекта. Это позволяет написать универсальный код для управления доступом к свойствам класса.

Решение
Это делается при помощи экспериментального расширения перегрузки; кроме того, надо написать методы __get() и __set() для перехвата запросов свойств.

Обсуждение
Перегрузка свойств позволяет без труда скрыть от пользователя истинное расположение свойств объекта и структуру данных, в которой они хранятся.

Например, класс pc_user, приведенный в примере 7.1, хранит переменные в массиве $data.

Пример 7.1. 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. Можно также избежать извлечения всей информации о пользователе за один раз и запрашивать ее по мере необходимости.

Другой альтернативой является использование более устойчивого механизма хранения данных, такого как файлы, разделяемая память или база данных.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Динамическая реализация объекта
Динамическое создание класса
Добавление свойств в базовый объект
Доступ к переопределенным методам
Клонирование объектов

Вернуться в раздел: PHP / 7. Классы и объекты