view raw
w00 w00 - 8 months ago 23
PHP Question

A php plugin architecture

I'm trying to think of a way to create a plugin architecture for my own framework. I've read numerous topics and post here and on other sites. And basically i've came to the following solution which seems to be the only good option in PHP (currently).

The idea is that every class extends a sort of observer like class. So a Template class, BaseController etc. always extend a Plugin class.

class BaseController extends Plugin
public function __construct()
// Plugin check, notify all loaded plugins

// Init some standard stuff
$this->view = new Template();
$this->baseLayout = 'layout.html';

$this->something = new Something();

// Plugin check, notify all loaded plugins

So what basically happends here is that when an indexController extends a baseController a plugin check is done. In this case for the constructor. This can be convenient when you want to do a some sort of login check with a plugin, before an Action method is actually invoked.

The Plugin class can resolve from what class is got called from and knows for what functions to look for in the loaded plugins.

Also note that it checks the loaded plugin list 2 times. One before anything is loaded (early) in the constructor, and one when all vars are loaded (late).

I can also add variables to the "checkForLateHooks()" function. So the hook functions can manipulate those too, like the 'baseLayout' variable.

A hook function would look like this:

public function hookConstruct ( &$baseLayout )
$baseLayout = 'login.html';

Now basically my question is, is this approach any good? I know there are probably alot of other ways to do it too. But i mainly don't want to run into design problems later on. It seems like a good idea now, but you never know how things work out later on...

If i remember it right (from all the posts the i've read), this is kinda like WordPress does it (and some other frameworks).


There are certainly many different ways to design a plugin system and perhaps asking on would give you more ideas, but I'll try to help by sharing my ideas and experience.

My "own" framework have grown considerably and have been adopted by many developers and companies. However the extensibility and ability to create and distribute plugins was a big request for the 4.2 version. I have decided to significantly improve based on some ideas from Ruby on Rails as well as many internal concepts. The general information about the add-ons is here:

How add-ons work

Generally, addon is just a collection of classes. They must not conflict with other addons or the core classes, therefore they reside in a separate namespace. Developer consults documentation of a plug-in and decides how to include it. Add-ons do not automatically initialize:


As you have mentioned, then it's down to hooks. The initial code registers callables inside other objects. The "API" is a good place to exchange some hooks, however it's also possible to place hooks inside other objects, such as forms, authentication class, etc.

The hook is called like this:

function myHook($caller,$arg1,$arg2){

Hooks may return result or even call breakHook, which raises exception, catches it inside the hook() function and thus preventing other hooks from being executed.


The hooks are used for "method injecting", basically mapping __call() to a hook registered by external controller. It's not a good development practice, but can make things easier for developers by add-on designers. There is also a hook which is called by all objects when they are initialized, and that one can be used to intercept anything even substitute objects with another objects.

Overall, I think I have about 20 different hooks inside the files to use. Some are executed multiple times or inside different instances of same class.

Class substitution

Ability to substitute class with your own is really important. For example in my framework it has a standard UI classes such as "Form". So Add-on my just use that class:


The Form class is defined like this in the framework:

class Form extends Form_Basic {}

Which makes it possible for user to override class definition and therefore make add-on use form class of their choice.


I think add-on deign boils down to:

  • simplicity of installation and use
  • avoiding conflicts between add-ons
  • defining different add-on types - authentication, UI, behavior
  • registering call-backs inside add-on
  • give a lot of power to add-ons without sacrificing performance

But also if you intend to grow your framework:

  • allowing user inherit your add-on classes and extend
  • allowing other add-ons depend on yours
  • make submitting add-ons easily into central repository for 3rd parties
  • clearly defining how add-ons must be written

For your structure, I'd suggest to place many more call-backs and make plugins decide which ones to use. Here is the example of the add-on in Agile Toolkit which add's "remember me" checkbox to the default login screen: