Karel Kozlik schreef: > Hello, > thanks for the hint. It looks nice. Where could I learn more about > $class::$method() syntax? I was not successfull when searching in php > manual. er, dunno - I picked it up on the internals mailing list I think, you might wnat to search that. > Btw. is it an intended behaviour that $class::$method() works in this > way? I mean that I would pressume that method is called in static > context and the $this should not be avaiable in the method than. So I > affraid a bit that the behaviour will be changed in the (near) future. this is intentional, it isn't going to change ... yes it is weird, we had a thread about this issue before not long ago on this list where someone thought it was a bug (I concurred until I was corrected). > But there still remains two issues: > 1. How to pass arguments to method? The number of arguments is different > for each method. So is the only way to construct a string containing the > arguments and use eval()? Or is there an another way? then use call_user_func() and/or call_user_func_array() inside __call(), although given the seemingly 'broken' (mho) design and infinite variations that are possible in terms of method argument invocation you might consider tackling the whole system from a wider perspective (probably not what you want to hear I guess) also see: http://bugs.php.net/bug.php?id=40694 basically the by-ref issue is not, seemingly, really solvable - I'd say using by-ref in most cases is unwarranted anyway ... but, you may be able to work round it by using a static variable inconjunction with a, second, retrieval method in the decorating classes that overcome the requirement for by-ref ... if that makes sense. looks like you have your work cut out for you! > > 2. Arguments sometimes need to be passed by reference. It seems that > __call() does not support passing arguments by reference :(. So I have > not idea how workaround it. > > thanks, > Karel > > > Jochem Maas napsal(a): >> 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