On Wed, 2011-01-19 at 01:07 -0600, Larry Garfield wrote:
> Hi all.  I'm trying to come up with a solution to an architectural problem I 
> could use some extra eyes on.
> I have (or will have) a large code base with lots of classes, spread out over 
> many optional plugin components.  These classes, of course, will have 
> interfaces on them.  These classes will, of course, lazy-load using PHP's 
> autoload capability.
> What I need to know is which classes implement which interfaces, so that I 
> can 
> load and use "all classes that implement interface Foo".  
> There are a couple of approaches that I've considered, all of which I dislike 
> for one reason or another.
> 1) Magic file naming.  That is, any class that implements interface Foo lives 
> in a $something.Foo.inc file, or some similar pattern.  This has a number of 
> problems.  First, it means a huge number of file_exists() calls to determine 
> if a given potential class exists, and then disk hits to load those files.  
> While that information is possible to cache, it also means that we cannot 
> have 
> a class that implements two of the interfaces I'm interested in (a feature I 
> will need) because then it would have to live in two files, which is clearly 
> impossible.
> 2) Reflection.  PHP makes it quite easy to get a list of all loaded classes, 
> and to get a list of all interfaces that a loaded class implements.  The 
> catch 
> there is "loaded".  Reflection only works once you've loaded the code file 
> into memory.  Once you've done so, you cannot unload it.  That means the code 
> is sitting there in memory wasting space.  Given the size of the code base in 
> question, that could easily blow out the process memory limit.  Even if we 
> cache that information we derive from reflection we still have to load it the 
> first time (or periodically when rebuilding the cache), which will blow the 
> memory limit.  The only alternative would be to have some sort of incremental 
> rebuild across a multi-request batch process, the complexity of which makes 
> my 
> skin crawl.
> 3) Static analysis.  Instead of reflection, either tokenize or string parse 
> all files to determine what classes implement what interfaces and then cache 
> that information.  We are actually using this method now to locate classes, 
> and it works surprisingly well.  Because we never parse code into memory it 
> does not ever spike the memory usage.  However, it is impossible to determine 
> if a class implements a given interface by static analysis unless it declare 
> so itself with the implements keyword.  If it does so indirectly via 
> inheritance, either via the class or via the interface, it would not find it. 
> That necessitates that any "detectable" classes must explicitly themselves 
> declare their interfaces, even if it is redundant to do so.  I don't like 
> that 
> approach, but it's the first one that strikes me as even viable.
> 4) Explicit declaration.  In this approach we detect nothing and rely on the 
> plugin developer to do everything.  That is, they must provide somewhere 
> (either in code or a configuration file) an index of all classes they offer, 
> the interfaces they implement, and the file in which they live.  While this 
> makes the implementation easy, it is a huge burden on the plugin developer 
> and 
> I'm quite sure they'll forget to do so or get it wrong on a regular basis.
> 5) Wave a wand and let the magic ponies figure it out.  I wish. :-)
> Can anyone suggest a better alternative?  At the moment option 3 seems like 
> the most viable approach, but I'm not wild about the implied performance 
> impact nor the potentially redundant interface definitions it would require.
> --Larry Garfield

My suggestion, would be for #5. The magic ponies do wonderful work.


Steve (TheStapler) Staples.

PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to