Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-31 Thread Mark
On Tue, Aug 28, 2012 at 1:43 PM, Matijn Woudt tijn...@gmail.com wrote:
 On Tue, Aug 28, 2012 at 1:16 AM, Larry Garfield la...@garfieldtech.com 
 wrote:
 On 8/27/12 6:11 PM, Matijn Woudt wrote:

 You should never be calling require() yourself.  Just follow the PSR-0
 naming standard and use an autoloader, then you don't have to even think
 about it.  There are many existing autoloaders you can use, including
 Composer's, Symfony2's, and probably Zend has one as well.


 I believe there's one in PHP by default now called SPLClassLoader or
 something like that..

 - Matijn


 There was a proposal for one, but it was never added.  You still need a
 user-space class loader for PSR-0, but they're readily available.


 --Larry Garfield


 Ah thanks for the info. I heard about it way back and assumed it was
 implemented by now ;)

 - Matijn

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


I did some searching on that one since it sounds interesting. It's
laying dormant in bugzilla: https://bugs.php.net/bug.php?id=60128 (the
RFC : https://wiki.php.net/rfc/splclassloader)
Thanks for the advice so far. I will certainly implement Autoloading.
Why didn't i think of that :p Guess my PHP knowledge is a bit rusty
since i did make autoloaders before.

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



Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-28 Thread Matijn Woudt
On Tue, Aug 28, 2012 at 1:16 AM, Larry Garfield la...@garfieldtech.com wrote:
 On 8/27/12 6:11 PM, Matijn Woudt wrote:

 You should never be calling require() yourself.  Just follow the PSR-0
 naming standard and use an autoloader, then you don't have to even think
 about it.  There are many existing autoloaders you can use, including
 Composer's, Symfony2's, and probably Zend has one as well.


 I believe there's one in PHP by default now called SPLClassLoader or
 something like that..

 - Matijn


 There was a proposal for one, but it was never added.  You still need a
 user-space class loader for PSR-0, but they're readily available.


 --Larry Garfield


Ah thanks for the info. I heard about it way back and assumed it was
implemented by now ;)

- Matijn

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



Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-27 Thread Stuart Dallas
On 26 Aug 2012, at 19:42, Mark mark...@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

 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?

 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.

-Stuart

-- 
Stuart Dallas
3ft9 Ltd
http://3ft9.com/

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



Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-27 Thread Mark
On Mon, Aug 27, 2012 at 12:41 PM, Stuart Dallas stu...@3ft9.com wrote:
 On 26 Aug 2012, at 19:42, Mark mark...@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.

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



Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-27 Thread Stuart Dallas
On 27 Aug 2012, at 14:29, Mark mark...@gmail.com wrote:

 On Mon, Aug 27, 2012 at 12:41 PM, Stuart Dallas stu...@3ft9.com wrote:
 On 26 Aug 2012, at 19:42, Mark mark...@gmail.com wrote:
 
 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.

I'm not sure I see what PluginLoader is doing? It makes more sense to me if you 
register like so:

PluginLoader::getInstance()-registerPlugin('PluginOne');

Then you get an instance of the plugin:

$plugin = PluginLoader::getInstance()-factory('PluginOne');

Tho, even then I don't see what the PluginLoader is adding to the party.

 Thank you for your advice, really appreciated.


No probs.

-Stuart

-- 
Stuart Dallas
3ft9 Ltd
http://3ft9.com/

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



Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-27 Thread Mark
On Mon, Aug 27, 2012 at 3:46 PM, Stuart Dallas stu...@3ft9.com wrote:
 On 27 Aug 2012, at 14:29, Mark mark...@gmail.com wrote:

 On Mon, Aug 27, 2012 at 12:41 PM, Stuart Dallas stu...@3ft9.com wrote:
 On 26 Aug 2012, at 19:42, Mark mark...@gmail.com wrote:

 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.

 I'm not sure I see what PluginLoader is doing? It makes more sense to me if 
 you register like so:

 PluginLoader::getInstance()-registerPlugin('PluginOne');

 Then you get an instance of the plugin:

 $plugin = PluginLoader::getInstance()-factory('PluginOne');

 Tho, even then I don't see what the PluginLoader is adding to the party.

Well, i'm making the classes up as i type. I don't actually have a
PluginLoader yet. Or rather, i'm just beginning to make it right now.
What it's doing is very simple. Read through the directory of the
plugins and load every single plugin it finds in memory. Then every
plugin registers the mime types it can handle. That information is
stored in the PluginLoader upon which some other place can call:
PluginLoader::pluginForMime(text/html). Though i still have to take
a good look at that.

But you're right, i can use the factory pattern here.

 Thank you for your advice, really appreciated.


 No probs.

 -Stuart

 --
 Stuart Dallas
 3ft9 Ltd
 http://3ft9.com/

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



Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-27 Thread Stuart Dallas
On 27 Aug 2012, at 14:52, Mark mark...@gmail.com wrote:

 On Mon, Aug 27, 2012 at 3:46 PM, Stuart Dallas stu...@3ft9.com wrote:
 On 27 Aug 2012, at 14:29, Mark mark...@gmail.com wrote:
 
 On Mon, Aug 27, 2012 at 12:41 PM, Stuart Dallas stu...@3ft9.com wrote:
 On 26 Aug 2012, at 19:42, Mark mark...@gmail.com wrote:
 
 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.
 
 I'm not sure I see what PluginLoader is doing? It makes more sense to me if 
 you register like so:
 
 PluginLoader::getInstance()-registerPlugin('PluginOne');
 
 Then you get an instance of the plugin:
 
 $plugin = PluginLoader::getInstance()-factory('PluginOne');
 
 Tho, even then I don't see what the PluginLoader is adding to the party.
 
 Well, i'm making the classes up as i type. I don't actually have a
 PluginLoader yet. Or rather, i'm just beginning to make it right now.
 What it's doing is very simple. Read through the directory of the
 plugins and load every single plugin it finds in memory. Then every
 plugin registers the mime types it can handle. That information is
 stored in the PluginLoader upon which some other place can call:
 PluginLoader::pluginForMime(text/html). Though i still have to take
 a good look at that.
 
 But you're right, i can use the factory pattern here.


Ahh, I see. Personally I'd go with the following (pseudocode)...

Inside the PluginLoader constructor (or other method)
  foreach (plugindir)
require plugindir/plugindir.php
$plugindir::init($this)

The static init() method calls PluginLoader::registerPlugin('mime/type', 
'PluginClassName'). Then pluginForMime does a lookup for the mime type and 
returns an object of the corresponding type. That way a single plugin can 
support multiple mime types.

-Stuart

-- 
Stuart Dallas
3ft9 Ltd
http://3ft9.com/

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



Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-27 Thread Mark
On Mon, Aug 27, 2012 at 4:26 PM, Stuart Dallas stu...@3ft9.com wrote:
 On 27 Aug 2012, at 14:52, Mark mark...@gmail.com wrote:

 On Mon, Aug 27, 2012 at 3:46 PM, Stuart Dallas stu...@3ft9.com wrote:
 On 27 Aug 2012, at 14:29, Mark mark...@gmail.com wrote:

 On Mon, Aug 27, 2012 at 12:41 PM, Stuart Dallas stu...@3ft9.com wrote:
 On 26 Aug 2012, at 19:42, Mark mark...@gmail.com wrote:

 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.

 I'm not sure I see what PluginLoader is doing? It makes more sense to me if 
 you register like so:

 PluginLoader::getInstance()-registerPlugin('PluginOne');

 Then you get an instance of the plugin:

 $plugin = PluginLoader::getInstance()-factory('PluginOne');

 Tho, even then I don't see what the PluginLoader is adding to the party.

 Well, i'm making the classes up as i type. I don't actually have a
 PluginLoader yet. Or rather, i'm just beginning to make it right now.
 What it's doing is very simple. Read through the directory of the
 plugins and load every single plugin it finds in memory. Then every
 plugin registers the mime types it can handle. That information is
 stored in the PluginLoader upon which some other place can call:
 PluginLoader::pluginForMime(text/html). Though i still have to take
 a good look at that.

 But you're right, i can use the factory pattern here.


 Ahh, I see. Personally I'd go with the following (pseudocode)...

 Inside the PluginLoader constructor (or other method)
   foreach (plugindir)
 require plugindir/plugindir.php
 $plugindir::init($this)

 The static init() method calls PluginLoader::registerPlugin('mime/type', 
 'PluginClassName'). Then pluginForMime does a lookup for the mime type and 
 returns an object of the corresponding type. That way a single plugin can 
 support multiple mime types.

 -Stuart

 --
 Stuart Dallas
 3ft9 Ltd
 http://3ft9.com/

That sounds sane and i probably go for that :)
Thanks for clarifying it a little.

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



Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-27 Thread Larry Garfield

On 8/27/12 4:09 PM, Mark wrote:

On Mon, Aug 27, 2012 at 4:26 PM, Stuart Dallas stu...@3ft9.com wrote:



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.


I'm not sure I see what PluginLoader is doing? It makes more sense to me if you 
register like so:

PluginLoader::getInstance()-registerPlugin('PluginOne');

Then you get an instance of the plugin:

$plugin = PluginLoader::getInstance()-factory('PluginOne');

Tho, even then I don't see what the PluginLoader is adding to the party.


Well, i'm making the classes up as i type. I don't actually have a
PluginLoader yet. Or rather, i'm just beginning to make it right now.
What it's doing is very simple. Read through the directory of the
plugins and load every single plugin it finds in memory. Then every
plugin registers the mime types it can handle. That information is
stored in the PluginLoader upon which some other place can call:
PluginLoader::pluginForMime(text/html). Though i still have to take
a good look at that.

But you're right, i can use the factory pattern here.



Ahh, I see. Personally I'd go with the following (pseudocode)...

Inside the PluginLoader constructor (or other method)
   foreach (plugindir)
 require plugindir/plugindir.php
 $plugindir::init($this)

The static init() method calls PluginLoader::registerPlugin('mime/type', 
'PluginClassName'). Then pluginForMime does a lookup for the mime type and 
returns an object of the corresponding type. That way a single plugin can 
support multiple mime types.

-Stuart

--
Stuart Dallas
3ft9 Ltd
http://3ft9.com/


That sounds sane and i probably go for that :)
Thanks for clarifying it a little.


You should never be calling require() yourself.  Just follow the PSR-0 
naming standard and use an autoloader, then you don't have to even think 
about it.  There are many existing autoloaders you can use, including 
Composer's, Symfony2's, and probably Zend has one as well.


Also, the key question is how you'll be mapping your situation to the 
plugin you need.  If it's fairly hard-coded (i.e., mime type of foo = 
class Bar), then just use a simple dependency injection container like 
Pimple.  If it's more complex and situational, then yes a factory is the 
easiest approach.


--Larry Garfield

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



Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-27 Thread Matijn Woudt
On Tue, Aug 28, 2012 at 12:58 AM, Larry Garfield la...@garfieldtech.com wrote:
 On 8/27/12 4:09 PM, Mark wrote:

 On Mon, Aug 27, 2012 at 4:26 PM, Stuart Dallas stu...@3ft9.com wrote:


 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.


 I'm not sure I see what PluginLoader is doing? It makes more sense to
 me if you register like so:

 PluginLoader::getInstance()-registerPlugin('PluginOne');

 Then you get an instance of the plugin:

 $plugin = PluginLoader::getInstance()-factory('PluginOne');

 Tho, even then I don't see what the PluginLoader is adding to the
 party.


 Well, i'm making the classes up as i type. I don't actually have a
 PluginLoader yet. Or rather, i'm just beginning to make it right now.
 What it's doing is very simple. Read through the directory of the
 plugins and load every single plugin it finds in memory. Then every
 plugin registers the mime types it can handle. That information is
 stored in the PluginLoader upon which some other place can call:
 PluginLoader::pluginForMime(text/html). Though i still have to take
 a good look at that.

 But you're right, i can use the factory pattern here.



 Ahh, I see. Personally I'd go with the following (pseudocode)...

 Inside the PluginLoader constructor (or other method)
foreach (plugindir)
  require plugindir/plugindir.php
  $plugindir::init($this)

 The static init() method calls PluginLoader::registerPlugin('mime/type',
 'PluginClassName'). Then pluginForMime does a lookup for the mime type and
 returns an object of the corresponding type. That way a single plugin can
 support multiple mime types.

 -Stuart

 --
 Stuart Dallas
 3ft9 Ltd
 http://3ft9.com/


 That sounds sane and i probably go for that :)
 Thanks for clarifying it a little.


 You should never be calling require() yourself.  Just follow the PSR-0
 naming standard and use an autoloader, then you don't have to even think
 about it.  There are many existing autoloaders you can use, including
 Composer's, Symfony2's, and probably Zend has one as well.


I believe there's one in PHP by default now called SPLClassLoader or
something like that..

- Matijn

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



Re: [PHP] What's the best way to make a dynamic plugin architecture?

2012-08-27 Thread Larry Garfield

On 8/27/12 6:11 PM, Matijn Woudt wrote:


You should never be calling require() yourself.  Just follow the PSR-0
naming standard and use an autoloader, then you don't have to even think
about it.  There are many existing autoloaders you can use, including
Composer's, Symfony2's, and probably Zend has one as well.



I believe there's one in PHP by default now called SPLClassLoader or
something like that..

- Matijn


There was a proposal for one, but it was never added.  You still need a 
user-space class loader for PSR-0, but they're readily available.


--Larry Garfield

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



[PHP] What's the best way to make a dynamic plugin architecture?

2012-08-26 Thread Mark
Hi,

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.
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.

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

Cheers,
Mark

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