Karel Kozlik schreef: >> >>> 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(), > > I tryed it, but it unfortunately does not work. In this case the method > is called in static context and the $this is not avaiable in the method. > > I tryed both: > call_user_func_array(array($class, $method), $args); > and > call_user_func_array($class."::".$method, $args); oh yeah d'oh. silly me, that's why I suggested the php5.3+ syntax in the first place. > >> 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. >> > > Hmmm I am not sure if I understand correctly, but I guess the use of > second, retrieval method will require changes in all methods that use > the by-ref arguments and also at all places where these methods are > called. Am I right? that's what I meant. > Better doing this I will think how to change the > whole design, but this is what I wanted to avoid. > take a look at interfaces, with the intention that you normalize the method signatures. additionally take a hard look as to whether you needs so many 'decorator' classes, I can imagine that there will be quite a bit of code that can be refactored into something more generic. big job, but it keeps you off the street ;-) > > thanks for your help > K. > >> 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