Форумы портала PHP.SU » » Объектно-ориентированное программирование » Паттерн Registry и множество его объектов

Страниц (1): [1]
 

1. sKaa - 26 Ноября, 2011 - 17:19:06 - перейти к сообщению
Спойлер (Отобразить)

Итак : Как видно класс реализует 2 интерфейса ArrayAccess и Countable значит нам доступен такой синтаксис :
PHP:
скопировать код в буфер обмена
  1.  
  2. $Registry = new Registry;
  3. $Registry['test'] = 123;
  4. $Registry['test2'] = 321;
  5.  
  6. echo count($Registry); // Выведет 2
  7. echo $Registry->count; // Выведет 2  
  8.  
  9.  

Ну об этих интерфейсах уже давно всем всё известно. Внимание вопрос :
PHP:
скопировать код в буфер обмена
  1.  
  2. $Registry->qwe = 123;
  3. $Registry->test = 321;
  4. $Registry->Application = & new Application;
  5.  


Как посчитать объекты в такой реализации?
2. Мелкий - 26 Ноября, 2011 - 17:23:13 - перейти к сообщению
sKaa пишет:
Как посчитать объекты в такой реализации?

Реализовать __set и __get.
3. sKaa - 26 Ноября, 2011 - 17:25:04 - перейти к сообщению
Подробней пожалуйста Улыбка А лучше пример )
4. Stierus - 28 Ноября, 2011 - 08:56:52 - перейти к сообщению
__set + __get + http://ru.php.net/manual/en/class.countable.php
5. morph-x - 28 Ноября, 2011 - 18:24:07 - перейти к сообщению
Методы __set и __get вызываются при попытке доступа к (несуществующему) полю объекта. Вот пример:

PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.  
  3. class Registry implements ArrayAcces, Countable {
  4.     private $data = array();
  5.  
  6.     ...
  7.  
  8.     public function __set($name, $value) {
  9.         $this->data[$name] = $value;
  10.     }
  11.  
  12.     public function __get($name) {
  13.         return $this->data[$name];
  14.     }
  15.  
  16.     ...
  17.  
  18. }
  19.  
  20. ?>

Теперь при попытке записи/чтения какого-либо параметра в реестре управление будет передаваться методам __get или __set соответственно. А они уже будут работать с массивом $data.
6. sKaa - 28 Ноября, 2011 - 18:38:47 - перейти к сообщению
Спасибо я уже разобрался. Дело в том, что если использовать магические __set и __get
не скалярные величины нельзя передать по ссылке
PHP:
скопировать код в буфер обмена
  1.  
  2. $Config['mysql_username'] = 'root';
  3. $Config['mysql_password'] = '123';
  4.  
  5. $Registry = new Registry;
  6. $Registry->Config = & $Config;
  7.  

Вызовет ошибку :
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. Notice: Indirect modification of overloaded property Registry::$Config has no effect in C:\www\tm\Index.php on line 50 Fatal error: Cannot assign by reference to overloaded object in C:\www\tm\Index.php on line 50
  3.  


Решение тоже есть :
PHP:
скопировать код в буфер обмена
  1.  
  2. public function __set($key, $var){
  3.                 if(is_scalar($var))
  4.                         $this->data[$key] = & $var;
  5.                 else $this->data[$key] =  $var;
  6.                 }
  7.  


Но тут новая проблема :
PHP:
скопировать код в буфер обмена
  1.  
  2. $Registry = new Registry();
  3. $Registry->Page->Current = 3;
  4. $Registry->Page->Next = 4;
  5. $Registry->Page->Prev = 2;
  6.  

Каждая из строчек вызовет по ошибке. (кроме экземпляра класса)
7. morph-x - 28 Ноября, 2011 - 19:01:12 - перейти к сообщению
Может лучше тогда наследовать класс ArrayObject ? Так в ZF сделан класс Registry.
(Добавление)
Вот, привожу две цитаты с документации:

Цитата:
Вы можете также обращаться к элементам, сохраненным в реестре, как к элементам массива, поскольку класс реестра наследует от ArrayObject.

Но там дальше уже видно, что обращаться можно и как к элементам массива, и как к объектам.

Цитата:
Сохраняемое значение может быть объектом, массивом или скаляром.

Вроде, то что вам нужно, или нет?
8. sKaa - 28 Ноября, 2011 - 19:16:34 - перейти к сообщению
Вроде да. Сейчас тогда скачаю Zend Framework. Погляжу как там дела с этим обстоят.
9. morph-x - 28 Ноября, 2011 - 19:26:49 - перейти к сообщению
Вот, нашел там библиотеку реестра в ZF (library/Zend/Registry.php):

Спойлер (Отобразить)

 

Powered by ExBB FM 1.0 RC1