Karel Kozlik schreef: > Hello list! > > I am using in my application dynamic method appending to class with > aggregate_methods() function. But this function is no more aviable in > php5 and runkit extension seems not to be maintained any more. So I > would like to replace it with something more common (__call method or so). > > Just to describe the situation (simplified). There is one common class > containing some common functions: > > class DataLayer{ > > function add_method($method){ > aggregate_methods($this, "DataLayer_".$method); > } > > function common_funct_foo(){ > ... > } > > function common_funct_bar(){ > ... > } > } > > > And there is hundreds of data manipulation methods (defined within > separate classes) which could call common functions. E.g.: > > > class DataLayer_get_items{ > function get_items(){ > $this->common_funct_foo(); > return something; > } > } > > And they could also call other dynamicaly added methods: > > class DataLayer_update_attr{ > function update_attr(){ > $this->get_items(); > $this->common_funct_bar(); > return; > } > } > > All the stuff is used e.g. in this way: > > $data = new DataLayer(); > $data->add_method('get_items'); > $data->add_method('update_attr'); > $data->update_attr(); > > > > Now the question is whether is it possible to somehow replace > functionality of add_method() without aggregate_methods() or > runkit_class_adopt(). And _WITHOUT_ need to change the hundreds of > DataLayer_* classes. The change should be only in the main DataLayer class. > I was thinking about __call() method, but I do not know how to deal > with the $this in dynamicaly appended functions. I need somehow make to > $this in these functions reference to instance of DataLayer class. __call() will allow you to do this, although you will need php5.3: <?php class DataLayer_update_attr { function update_attr() { echo __METHOD__, "\n"; $this->common_funct_bar(); $this->get_items(); return; } } class DataLayer { function common_funct_foo() { echo __METHOD__, "\n"; /* ... */ } function common_funct_bar() { echo __METHOD__, "\n"; /* ... */ } function __call($method, $args) { $class = "DataLayer_{$method}"; echo __METHOD__, " ... trying {$class}::{$method}()\n"; if (!class_exists($class, true)) // trigger autoload throw new Exception("buddy we don't have a $class, so $method is not callable"); $class::$method(); } } $d = new DataLayer; $d->update_attr(); ?> ----- output ------ [22:11:16] jochem::~/test > ~/src/php5.3-200808312030/sapi/cli/php -n -f ./class_agg.php DataLayer::__call ... trying DataLayer_update_attr::update_attr() DataLayer_update_attr::update_attr DataLayer::common_funct_bar DataLayer::__call ... trying DataLayer_get_items::get_items() Fatal error: Uncaught exception 'Exception' with message 'buddy we don't have a DataLayer_get_items, so get_items is not callable' in /Users/jochem/test/class_agg.php:30 Stack trace: #0 [internal function]: DataLayer->__call('get_items', Array) #1 /Users/jochem/test/class_agg.php(11): DataLayer->get_items() #2 /Users/jochem/test/class_agg.php(32): DataLayer_update_attr->update_attr() #3 [internal function]: DataLayer->__call('update_attr', Array) #4 /Users/jochem/test/class_agg.php(37): DataLayer->update_attr() #5 {main} thrown in /Users/jochem/test/class_agg.php on line 30 > > Any ideas? > > many thanks, > Karel > > -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php