Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:64949 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 45271 invoked from network); 14 Jan 2013 20:15:59 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 14 Jan 2013 20:15:59 -0000 Authentication-Results: pb1.pair.com header.from=lisachenko.it@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=lisachenko.it@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.220.176 as permitted sender) X-PHP-List-Original-Sender: lisachenko.it@gmail.com X-Host-Fingerprint: 209.85.220.176 mail-vc0-f176.google.com Received: from [209.85.220.176] ([209.85.220.176:57560] helo=mail-vc0-f176.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 9E/49-22727-D7764F05 for ; Mon, 14 Jan 2013 15:15:58 -0500 Received: by mail-vc0-f176.google.com with SMTP id fo13so3895736vcb.7 for ; Mon, 14 Jan 2013 12:15:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=DqUcY1BN6ebxRSGdp1AYbCOMXXJmFB9AkFSWcWC1Cbs=; b=LS7Js7V7mFRLoyhF7zUo1aids5tIHvfauDEKgzhpeL2hwZymVZFcHLX41iaNKYoTLw zWkJHt02LYML+d7pdMWrm7GJBHWjsjFUj40epFno+e7GQVW7JDnE8Q5katd/KNW5CgxV z49PhHdd68uu6TPkpYmxnl694l5y8wwyIf58HXiGehM0COoLME5D0CtDO2rT93eoWMNV ys1fRRLPX1f9dkYVgU1l3CerhogTe/BpLCDHSaCoZ8E2OcZSfb1A2BMyrmRC9uLBBYR8 3O3jgA+JhvOs5OA7yYdTYYQ9pec5V+4mtELq00i2p4HXZHJ7n2VxPMF446VXqOJS0Z5u C9Qw== MIME-Version: 1.0 Received: by 10.52.97.104 with SMTP id dz8mr90789213vdb.21.1358194554017; Mon, 14 Jan 2013 12:15:54 -0800 (PST) Received: by 10.59.6.42 with HTTP; Mon, 14 Jan 2013 12:15:53 -0800 (PST) In-Reply-To: References: Date: Tue, 15 Jan 2013 00:15:53 +0400 Message-ID: To: Sebastian Krebs Cc: PHP internals list Content-Type: text/plain; charset=UTF-8 Subject: Re: [PHP-DEV] [Reflection] Improve logic of ReflectionMethod->invokeArgs() for static methods From: lisachenko.it@gmail.com (Alexander Lissachenko) 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: 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 : > > > > 2013/1/14 Alexander Lissachenko >> >> 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 : >> > >> > >> > >> > 2013/1/14 Alexander Lissachenko >> >> >> >> 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? >> > >> > > > 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