Maybe I can help explain a good example on were this is useful as I also suggested this improvement and created the patch for it: (http://bugs.php.net/bug.php?id=62113)
This is actually something I am using in one of my primary projects as a framework (this example shows the concept not the actual code I am using). This allows you to create new "Models" and extend (using traits) the specific functions you'd like to attach to each extended model class. /* Was a bit large so I posted here */ https://gist.github.com/4685694 There is a workaround so it was not super important for me to push for it to be implemented (see commented code from line: 13-24). Full breakdown of what it does: There is a primary "Model" abstract class which pre-defines and forces certain functions and variables to be set. There are various traits set which a user may define themselves that allow certain parts of the code to be "hooked" into and modify it's behavior without having to re-declare the entire function. The advantages to this is that it allows new Models to be added and extended without having to worry about replacing an entire function and losing any potential updates to the original function and gives the ability for multiple traits to hook themselves into specific functions. In this example I have 2 traits, "Check_Permissions" and "Log_Changes" which both do a dummed down version of their job... If a certain Model needs to be logged for when changes happen it can just add the trait "Log_Changes" to it and it will auto-hook into the update and create functions. If a certain model needs permission checks to update or insert it can extend the "Check_Permissions" trait. (although in my example one extends the "after" function hook and the other extends the "before" function hook, the idea of why it'd be useful is good enough). Although yes there is a workaround, the workaround requires a new closure to be created for each function being executed every time. but if the "ReflectionMethod::invokeArgs()" function would allow the first argument to be a string of class or the object itself it wants to bind too it would save a new closure from having to be created for every hook being executed. (Sorry for the long code, but I wanted to make sure I got my point across on why it'd be useful) Software Developer Nathan Bruer -----Original Message----- From: Alexander Lissachenko [mailto:lisachenko...@gmail.com] Sent: Monday, January 14, 2013 2:16 PM To: Sebastian Krebs Cc: PHP internals list Subject: Re: [PHP-DEV] [Reflection] Improve logic of ReflectionMethod->invokeArgs() for static methods Probably, it will be better to give a link to the one of examples of AOP integration for laravel framework (requires 5.4.10 to work): https://github.com/lisachenko/laravel-aspect (just clone, install dependencies and look at result) I need to perform weaving of aspects into the original methods, so here is an example of generated source code: <?php namespace Illuminate\Foundation; class AliasLoader__AopProxied { // .. source code here /** * Get or create the singleton alias loader instance. * * @param array $aliases * @return Illuminate\Foundation\AliasLoader */ public static function getInstance(array $aliases = array()) { if (is_null(static::$instance)) static::$instance = new static($aliases); $aliases = array_merge(static::$instance->getAliases(), $aliases); static::$instance->setAliases($aliases); return static::$instance; } /** * Load a class alias if it is registered. * * @param string $alias * @return void */ public function load($alias) { if (isset($this->aliases[$alias])) { return class_alias($this->aliases[$alias], $alias); } } // more source code here } class AliasLoader extends AliasLoader__AopProxied { /** *Property was created automatically, do not change it manually */ private static $__joinPoints = array(); // some source code here /** * Get or create the singleton alias loader instance. * * @param array $aliases * @return Illuminate\Foundation\AliasLoader */ public static function getInstance(array $aliases = array()) { return self::$__joinPoints['static:getInstance']->__invoke(get_called_class(), array($aliases)); } /** * Load a class alias if it is registered. * * @param string $alias * @return void */ public function load($alias) { return self::$__joinPoints['method:load']->__invoke($this, array($alias)); } // some source code here } You can notice, that original class name is pointing to the decorator class after weaving. Source code still use $class = new AliasLoader(), but the class now contains additional logic that was introduced by aspects. 2013/1/14 Sebastian Krebs <krebs....@gmail.com>: > > > > 2013/1/14 Alexander Lissachenko <lisachenko...@gmail.com> >> >> My use-case is weaving aspects into the methods. Yeah! ) >> >> So, I take the original class, rename it and then create a decorator >> class instead of original class with overridden dynamic and static >> methods. Method in the decorator should make some specific logic and >> then just invokes the original static method with Reflection, but the >> scope should be also correct. >> >> For example, previous class First will be renamed during load-time to >> the First_AopProxied: >> >> class First_AopProxied >> { >> public static function foo() >> { >> echo get_called_class(); >> } >> } >> >> and decorator will be created >> >> class First extends First_AopProxied >> { >> public static function foo() >> { >> // some logic here, that should call parent method and >> preserve the scope (class First) >> // can not use parent::foo() here, because around advice >> should be able to call this method somewhere in the closure... >> } >> } > > > I must say this example is not really better than the last one (it > feels like it is exactly the same with 2 lines more comments). Also I > don't know, what you mean by "call this method somewhere in the > closure"; which closure?!? > I guess you are in fact looking for regular instance methods. > >> >> >> 2013/1/14 Sebastian Krebs <krebs....@gmail.com>: >> > >> > >> > >> > 2013/1/14 Alexander Lissachenko <lisachenko...@gmail.com> >> >> >> >> Hi! It's my first letter here ) >> >> >> >> I want to suggest a small improvement for >> >> ReflectionMethod->invoke() and ReflectionMethod->invokeArgs() >> >> methods to support LSB for overridden static methods. Currently, >> >> for invoking static methods first argument should be null, >> >> information about class (scope) is taken from the reflection >> >> class. However, there is one issue that can not be solved at the current >> >> time. >> >> >> >> Suppose, we have two classes: >> >> >> >> class First >> >> { >> >> public static function foo() >> >> { >> >> echo get_called_class(); >> >> } >> >> } >> >> >> >> class Second extends First >> >> { >> >> public static function foo() >> >> { >> >> echo "Do not call me, please"; >> >> } >> >> } >> >> >> >> Now I want to invoke the First::foo() method with Reflection from >> >> the Second class scope for using LSB. Currently this is impossible: >> >> $class = new ReflectionClass('First'); >> >> $class->getMethod('foo')->invokeArgs(null, array()); // Outputs >> >> 'First' as no scope information is passed >> >> >> >> >> >> $class = new ReflectionClass('Second'); >> >> $class->getMethod('foo')->invokeArgs(null, array()); // Outputs >> >> 'Do not call me, please' as method is redefined >> >> >> >> So, there is no way now to invoke the static First::foo() method >> >> from the child scope because it was redefined. However, this can >> >> be easily implemented by adding the scope for static methods >> >> invocation (like >> >> Closure::bindTo()): >> >> >> >> $class = new ReflectionClass('First'); >> >> $class->getMethod('foo')->invokeArgs('Second', array()); // >> >> Outputs 'Second' >> >> >> >> This improvement can be very useful for building proxies for >> >> static methods, that use LSB. Can it be implemented for PHP 5.3-5.5? >> >> Thanks! >> > >> > >> > Maybe it's just me, but could you explain which use-case want to solve? >> > The >> > example isn't very useful, because you can achieve this quite easy >> > without reflection. Also why do you override the method, when you >> > don't want it to get called? Shouldn't they two separate methods >> > then? >> > >> > <?php >> > class First >> > { >> > public static function foo() >> > { >> > echo get_called_class(); >> > } >> > } >> > >> > class Second extends First >> > { >> > public static function foo() >> > { >> > echo "Do not call me, please"; >> > } >> > public static function bar() { >> > parent::foo(); >> > } >> > } >> > Second::bar(); >> > >> > http://codepad.viper-7.com/fwG5GB >> > >> >> >> >> >> >> -- >> >> PHP Internals - PHP Runtime Development Mailing List To >> >> unsubscribe, visit: http://www.php.net/unsub.php >> >> >> > >> > >> > >> > -- >> > github.com/KingCrunch > > > > > -- > github.com/KingCrunch -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php