Re: What's the best way to make a dynamic plugin architecture?
| From: | Mark | Date: | Mon, 27 Aug 2012 13:29:45 +0000 |
| Subject: | Re: What's the best way to make a dynamic plugin architecture? | ||
| References: | 1 2 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-318874@lists.php.net to get a copy of this message | ||
On Mon, Aug 27, 2012 at 12:41 PM, Stuart Dallas <stuart@3ft9.com> wrote:
> On 26 Aug 2012, at 19:42, Mark <markg85@gmail.com> wrote:
>
>> Envision the following plugin architecture:
>>
>> class PluginLoader
>> {
>> }
>>
>> interface PluginInterface
>> {
>> .. some function definitions ..
>> }
>>
>> class PluginOne implements PluginInterface
>> {
>> }
>>
>> class PluginTwo implements PluginInterface
>> {
>> }
>>
>> The PluginLoader is loading the plugins.
>> The PluginInterface defines an interface which each plugin has to implement.
>> PluginOne and PluginTwo are plugins that implement the interface.
>>
>> Each plugin (PluginOne and PluginTwo) are stored in their own folders.
>> So the folder structure would be somewhat like this:
>> |- Plugins
>> |- - PluginOne
>> |- - - PluginOne.php
>> |- - - other possible files
>> |- - PluginTwo
>> |- - - PluginTwo.php
>> |- - - other possible files
>> |- PluginLoader.php
>> |- PluginInterface.php
>>
>> Now making this structure isn't an issue. I can do all of that just
>> fine. The place where i'm actually going to make a plugin instance is
>> where things get a little more complicated. The PluginLoader simply
>> reads all the dirs in the Plugins folder and tries to find a filename
>> with the same dir. So if it reads the dir Plugins/PluginOne it will
>> try to include the PHP file: Plugins/PluginOne/PluginOne.php. That's
>> fine and working.
>>
>> To actually make a plugin instance i can do two things that i know of:
>> 1. use eval like so: eval('$obj = new '.$pluginName.'();'); and
>> register it to the PluginLoader.
>
> No need to use eval, you can simply do this:
>
> $obj = new $pluginName();
>
> See here: http://php.net/language.variables.variable
Ahh right, i completely forgot about that option. That might just work
the way i want it :)
>
>> 2. Let the plugin itself (so in this case PluginOne.php) open itself
>> and register it to the PluginLoader.
>>
>> With the first option i have to do eval which i try to avoid if possible..
>> With the second solution the PluginLoader probably has to be a singlethon.
>
> Why does it need to be a singleton?
Well, i would then do something like this from within the included
plugin file after the class:
PluginLoader::getInstance()->registerPlugin(new PluginOne());
Or something alike.
>
>> Now my question is: what is the right way of loading plugins like
>> this? Is there some other option then the two i described above? My
>> PHP limitations are the newest version so no limitation there :)
>> I'm kinda leaning towards the second option now since that seems to be
>> quite stable and not very error prone. The eval one is much easier to
>> break :p
>
> If you're happy for each plugin to be in a separate directory then what you have in option
> 1, minus the eval, will work perfectly well. I don't know what your use case is but if
> there's a chance a single plugin might want to provide several classes then I'd require an
> init.php in each plugin folder and have that register the class names with the class loader. It
> could also then pass along some meta information such as a description of what each class does. If
> this is for use in web requests you might want to stick to what you currently have as there's a
> lot less overhead.
Yeah, if i extend it more that will certainly be an requirement.
>
> -Stuart
>
> --
> Stuart Dallas
> 3ft9 Ltd
> http://3ft9.com/
Thank you for your advice, really appreciated.