За последние 24 часа нас посетили 17918 программистов и 1614 роботов. Сейчас ищут 1447 программистов ...

O_Object

Тема в разделе "Решения, алгоритмы", создана пользователем dark-demon, 12 июн 2008.

  1. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    PHP:
    1. <?php
    2.  
    3. class O_Object {
    4.  
    5.     protected $state= array();
    6.  
    7.     function &_create( ){ return new $this; }
    8.     function &__clone( ){ return $this->_create()->set__( $this->get__() ); }
    9.     function &__toString( ){ return print_r( $this, 1 ); }
    10.     function &__sleep( ){ return array( 'state' ); }
    11.  
    12.     function &__get( $name ){
    13.         $names= explode( '_', $name );
    14.         $method= 'get_' . $names[0];
    15.         if( !method_exists( $this, $method ) ) return $this->_get( $names );
    16.         array_shift( $names );
    17.         return $this->{ $method }( $names );
    18.     }
    19.     function __set( $name, $value ){
    20.         $names= explode( '_', $name );
    21.         $method= 'set_' . $names[0];
    22.         if( !method_exists( $this, $method ) ) return $this->_set( $names, $value );
    23.         array_shift( $names );
    24.         return $this->{ $method }( $value, $names );
    25.     }
    26.  
    27.     function &_get( $names ){
    28.         if( is_string( $names ) ) $names= explode( '_', $names );
    29.         $cur= &$this->state;
    30.         foreach( $names as $name ):
    31.             if( !isset( $cur ) ) $cur= array();
    32.             if( strlen( $name ) ) $cur= &$cur[ $name ];
    33.             else $cur= &$cur[ ];
    34.         endforeach;
    35.         return $cur;
    36.     }
    37.     function _set( $names, $value ){
    38.         $val= &$this->_get( $names );
    39.         return $val= $value;
    40.     }
    41.  
    42.     function &get_( $names ){
    43.         $method= 'get__' . array_shift( $names );
    44.         return $this->{ $method }( $names ) ;
    45.     }
    46.     function set_( $value, $names ){
    47.         $method= 'set__' . array_shift( $names );
    48.         return $this->{ $method }( $value, $names ) ;
    49.     }
    50.  
    51.     function &get__( ){ return $this->state; }
    52.     function set__( $value, $names= array() ){ return $this->state= $value; }
    53.  
    54. } return new O_Object;
    55.  
    56. ?>
    57.  
    58. сие есть класс, реализующий базовый функционал, позволяющий солидно упростить реализацию других классов, но может использоваться и самостоятельно в качестве замены обычного дерева массивов.
    59.  
    60. позволяет:
    61.     перегружать разные свойства разными функциями
    62.     перегружать группы свойств одной функцией
    63.     реализует базовую поддержку "путей" для доступа ко вложенным значениям
    64.     реализует такие необходимые методы как:
    65.         засыпание
    66.         сериализация в строку
    67.         получение всего состояния в виде массива
    68.         создание новых объектов без необходимости знать имя класса
    69.  
    70. $state - тут хранится всё состояние объекта.
    71.  
    72. _create - создаёт новый чистый объект.
    73.     $obj2= $obj1->create()
    74.  
    75. __clone - создаёт клон объекта.
    76.     $obj2= clone( $obj1 )
    77.  
    78. __toString - возвращает дамп объекта.
    79.     echo $obj;
    80.  
    81. __sleep - позволяет объекту "засыпать".
    82.     $obj2= unserialize( $str= serialize( $obj1 ) );
    83.  
    84. __get, __set - глобалные геттер и сеттер. передают управление либо в один из частных геттеров или сеттеров (get_*, set_*), либо в дефолтный (_get, _set).
    85.  
    86. _get, _set - дефолтные геттер и сеттер. используют символ подчёркивания для навигации по деревянному массиву состояния. если, какого-либо ключа не существует - создают его. если по указанному пути значения небыло - вернёт null.
    87.     $obj->name= 'qwerty';                       # state['name']= 'qwerty';
    88.     $obj->names_0= 'qwerty';                    # state['names']['0']= 'qwerty';
    89.     $obj->names_= 'qwerty';                    # state['names'][]= 'qwerty';
    90.     $val= &$obj->tree___name; $val= 'qwerty';   # state['tree'][][]['name']= 'qwerty';
    91.  
    92. get_*, set_* - позволяют перегружають пути, по первому ключу.
    93.     function set_tree( ){ throw new Exception( 'это дерево ридонли' ) }   # $obj->tree= 1; // выдаст ошибку
    94.     другой пример - методы get_ и set_
    95.  
    96. get_, set_ - методы перегружающие доступ к свойствам, начинающихся с подчёркивания. выдают ошибку при попытке доступа к неперегруженным пропертям.
    97.  
    98. get__*, set__* - позволяют перегрузить низкоуровневые свойства (начинающиеся с подчёркивания).
    99.     function get__stdObject( ){ return (object)$this->state }   # echo $obj->_stdObject
    100.     другой пример - методы get__ и set__
    101.  
    102. get__, set__ - перегружают свойства, начинающиеся с двойного подчёркивания, либо имя которых состит из одного единственного подчёркивания. так как двойное подчёркивание забронировано за магическими методами - данные два метода используются только для прямого оперирования с состоянием объекта.
    103.  
     
  2. Anonymous

    Anonymous Guest

    Поправь разметку, плиз?
     
  3. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    с разметкой всё в порядке ;-)
     
  4. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    dark-demon
    Теперь пиши X_Xception :lol:
     
  5. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    о! это мысль!!! =)
     
  6. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    dark-demon
    Шутки в сторону, интересная идея и реализация.
    Правда, боюсь, тормозить будет :( у тебя практически все вызовы методов - непрямые.
     
  7. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    ой, да это мелочи :)
    операции с файлами/бд сожрут всю разницу.
    а вызовы методов, как раз, прямые. непрямой только доступ к свойствам.