1- Introduction

The architecture we present here
is based on the 'plugin' , 'inversion of control', or 'dependency injection'
design patterns. If you want to know more about the theory, you may find it
here.

Actually, after all this theory is thrown away, it becomes simpler :

it provides a way to extend a base software.

An extension is called a plugin.

In order to communicate with the base software, a plugin
must implement a given interface.

This interface acts as a contract between the base software and the
plugin, and is generally defined by an abstract class extended by the plugin's
code.

Such an architecture is very common. It is used by Apache, PHP, Firefox... Most software accepting
third-party extensions use this pattern.

As a package format, PHK is a
tool of choice to implement a plugin architecture, as it is much easier to
manage a plugin as a single file, rather than as a set of files. So, in order to
make it still easier, PHK
provides a mechanism specifically intended for plugins. If we use our
old-fashioned term of 'entry point', we can say that, typically, a library does not define
any entry point, a program defines one entry point, and a plugin defines
a whole set of
entry points. In PHK-compliant plugins, these entry points are implemented as methods in a
given class. The methods' names are generally defined by an abstract class (or
by an interface).

[:Note] In a typical configuration, a PHK archive used as a plugin is always included from
another script, and never directly executed, either in CLI or web mode.

How it works : when a PHK archive is included, if the 'plugin_class' option is
defined, an instance of this class is automatically created. The calling code
can then get this object using the PHK::plugin() static method.

2- Reserved methods

By convention, in a plugin, the method names starting with an underscore are
reserved for PHK. So, when implementing a plugin system, avoid such
names for your own methods.

2.1- Constructor

The class constructor
(__construct) receives the PHK package's mount point as argument.

2.2- The _webinfo() method

This method is
optional.

When the webinfo 'Info' page is displayed, or when the CLI
'@techinfo' command is run, PHK looks for a '_webinfo()' method in the package's
plugin (if it is defined). If this method exists, it is called and must
display some information about the plugin.

Prototype :

void _webinfo(boolean $html);

where the $html argument informs the method
wether it must display its result as HTML or plain text.

3- A basic example

First, we define a plugin
interface. This interface contains only one method, a sort of output filter supposed to display a
string. Note that there is no limit to the number of methods a
plugin can provide.

Here is the corresponding abstract class :

abstract class DisplayPlugin
{
public function display($string);
}

Now, we know that every plugin must define this method in a class
derived from this base class.
Here is such a class :