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 -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php