
1. Introduction |
2. Reserved methods |
2.1. Constructor |
2.2. The _webinfo() method |
3. A basic example |
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 |
Now, we know that every plugin must define this method in a class derived from this base class. Here is such a class :
class UpperDisplay extends DisplayPlugin |
Before building the archive, we need to specify which class implements the plugin interface. This is done by inserting the following option in the PSF file :
plugin_class: UpperDisplay |
Then, we build the plugin package. It only contains the class file and defines the plugin_class option. Here is a basic PSF to generate the package :
add
DisplayPlugin.php |
Now, in the base software, we load a plugin and use it to display a string :
class Display |
When creating an instance of the plugin class, the
corresponding PHP source is transparently loaded by the autoloader.
The main code could look like this :
$output=new Display(); |
Through this example, you can see how easy it is to implement a plugin mechanism in your software, using the PHK built-in features.
Implementing more complex plugin systems is just an extension of this basic example.