Здравствуйте, товарищи!
Все верчусь вокруг тем с http://forum.vingrad.ru/forum/topic-235165.html и http://forum.vingrad.ru/forum/topic-235417.html. Думаю вы уже читали эти темы в форуме. Вопросы эти очень заинтересовали, и постепенно я начал понимать, что слишком много чего недопонимаю, т.к. ранее не приходилось с этим работать, но желание все это осознать берет вверх, поэтому я прошу вашей помощи!
Нашел в сети некоторый скрипт (искал по запросу динамическое добавление функций в классы)
| Код | <?php Object::$prototype= new Object( array() ); class Object { static $prototype; var $delegates= array(); var $context= null; var $class= ''; function Object( $delegates= null ){ $this->context= $this; $this->class= get_class( $this ); if( func_num_args() ): if( is_array( $delegates ) ): $this->delegates= $delegates; else: $this->delegates= func_get_args(); endif; else: $this->delegates[]= eval( 'return ' . $this->class . '::$prototype;' ); endif; $this->constructor(); } function constructor( ){ } function take( $arr ){ foreach( $arr as $key => $val ) $this->$key= $val; } function haveDelegate( $object ){ return $this->_findByObj( $object ); } function _findByMethod( $method ){ if( method_exists( $this, $method ) ) return $this; foreach( $this->delegates as $ex ): if( $obj= $ex->_findByMethod( $method ) ) return $obj; endforeach; return null; } function _findByProp( $prop ){ if( isset( $this->$prop ) ) return $this; foreach( $this->delegates as $ex ) if( $obj= $ex->_findByProp( $prop ) ) return $obj; return null; } function _findByObj( $object ){ if( $this === $object ) return $this; foreach( $this->delegates as $ex ) if( $obj= $ex->_findByObj( $object ) ) return $obj; return null; } function apply( $obj, $method, $args ){ $context= $this->context; $this->context= $obj->context; $ret= call_user_func_array( array( $this, $method ), $args ); $this->context= $context; return $ret; } function __call( $method, $args ){ $obj= $this->_findByMethod( $method ); if( $obj ) $obj->apply( $this, $method, $args ); endif; $trace= debug_backtrace(); $file= $trace[1]['file']; $line= $trace[1]['line']; $class= $trace[1]['class']; trigger_error( "[ unknown method {$class}->{$method}() in {$file} on {$line} line ]" ); } function __get( $prop ){ $obj= $this->_findByProp( $prop); if( $obj ) return $obj->$prop; $trace= debug_backtrace(); $file= $trace[0]['file']; $line= $trace[0]['line']; $class= $trace[0]['class']; trigger_error( "[ unknown property {$class}->{$prop} in {$file} on {$line} line ]" ); } } Rect::$prototype= new Rect( Object::$prototype ); class Rect extends Object { static $prototype; var $width= 0; var $height= 0; function area( ){ return $this->context->width * $this->context->height; } } Rhomb::$prototype= new Rhomb( Object::$prototype ); class Rhomb extends Object { static $prototype; var $width= 0; var $height= 0; function area( ){ return $this->context->width * $this->context->height / 2; } } Figure::$prototype= new Figure( Object::$prototype ); class Figure extends Object { static $prototype; }
|
| Код | <?php Deque::$prototype= new Deque( Object::$prototype ); Deque::$prototype->data= array(); class Deque extends Object { static $prototype; function push( ){ $this->context->adds(); foreach( func_get_args() as $val ) array_push( $this->context->data, $val ); return $this->context; } function unshift( ){ $this->context->adds(); foreach( func_get_args() as $val ) array_unshift( $this->context->data, $val ); return $this->context; } function pop( ){ $this->context->adds(); return array_pop( $this->context->data ); } function shift( ){ $this->context->adds(); return array_shift( $this->context->data ); } function adds( $arr= array() ){ if( !isset( $this->context->data ) ) $this->context->data= $this->context->data; foreach( $arr as $key => $val ) $this->context->push( $val ); return $this->context; } function contains( $value ){ foreach( $this->context->data as $val ): if( $value === $val ) return $val; endforeach; return null; } function drop( $value ){ $this->context->adds(); foreach( $this->context->data as $key => $val ): if( $value === $val ) unset( $this->context->data[ $key ] ); endforeach; return null; } function join( $del= '' ){ $first= true; $str= ''; $data= $this->context->data; foreach( $data as $val ): if( !$first ) $str.= $del; $str.= $val; $first= false; endforeach; return $str; } function __toString( ){ return $this->context->class . '[ ' . $this->context->join( ', ' ) . ' ]'; } } $arr1= new Deque; $arr2= new Deque; $arr1->adds( array( 'abc', 'def', 'ghi' ) )->drop( 'def' ); $arr2->push( $arr1, 123 ); $arr1->push( $arr1->contains( 'def' ) ? 1 : 0 ); $arr1->unshift( $arr1->contains( 'abc' ) ? '' : '8-(' ); echo $arr2->join( ' ' ) . '<br/>'; echo '<br/>'; $arr= new Deque; echo $arr . '<br/>'; Deque::$prototype->data= array( 'default data' ); echo $arr . '<br/>'; echo '<br/>'; $arr->adds( ); Deque::$prototype->data= array( 'another default data' ); echo $arr . '<br/>'; echo ( new Deque ) . '<br/>'; echo '<br/>'; ?>
|
Всякие патерны и синглетоны для меня достаточно новые слова, которые я как раз встретил пытаясь найти ответы на свои вопросы.
Прошу вас помочь понять о чем этот скрипт и как что от чего в нем работает. Например, в самом начале
| Код | Deque::$prototype= new Deque( Object::$prototype ); Deque::$prototype->data= array();
|
честно скажу не понимаю что это дает, опять таки потому что не сталкивался с таким ранее.
Буду премного благодарен за ссылки на полезные статьи по теме, чтобы углубленно понять что к чему в этом скрипте, и за любую вашу помощь!
Спасибо! |