Should all plugins be encapsulated in a Class?

When developing a plugin should the functions be grouped together into a Class to avoid namespace conflicts?

Yes, but that’s only one of the minor arguments. In-fact that’s not the “true” nature of a class in OOAD.

Does using classes create performance overheads for PHP?

No, not notably. Bad design and/or bad written code or pre-mature optimisation creates far more performance problems than actual language features.

If there is a performance hit, should function names just be pre-fixed instead?

As written, there is no performance hit. Bad written code will be more of a performance hit than good written code that has some more lines of code but does not force you to do bad things.


Bottom Line:

You can make differently use of classes for plugins. You can just use them to have some kind of namespace and use them “just” for global functions. The most direct form of that are static class functions, the following code-example shows both, first global functions, then global static class functions:

/* global function */
function myplug_hook()
{
}

add_filter('the_hook', 'myplug_hook');


/* global static function */
class myplug
{
    public static function hook()
    {
    }
}

add_filter('the_hook', 'myplug::hook');

This is just a little example showing that you need to type more for the single hook. Additionally it shows how the namespacing works: You can easier replace the single class name to rename all static functions and then search and replace myplug:: which could be harder with myplug_ because of false positives. But in the end there is not much difference.

The key point is: static class functions Docs are not really much else then global functionsDocs.

And this example shows as well: Namespacing is fine, but with worpdress, the namespacing stops with using hooks: The callback function is hardencoded, hence the benefit in namespacing using the class (one place for the base-name, the classname) does not help when you intervene your code with wordpress for the hook names.

The real benefit starts with using actual class instances and non-static functions. This has the benefit that you can start to make use of OO principles and you can streamline your code. Static class functions are more a problem than a solution infact.

Then it’s more than just syntactic sugar.

Key point is: Do something that helps you to write the code you can easily deal with and maintain. Don’t over-rate performance, that’s a common mistake. More important is that you write code that is easy to read and understand, that just does what you need. Maybe this question and answer is helpful for a bigger picture in this context: Multiple Custom Metabox Help.

One common approach I have even with smaller plugins is making use of a static helper function to instantiate the plugin and the rest resides within the plugin instance then. This helps to encapsulate the main plugin logic and it benefits from namespacing with the hooks as well that private members can be re-used between hooks which is not possible with standard global functions. The following code-example shows the pattern:

<?php
/** Plugin Headers ... */

return MyPlugin::bootstrap(); 

class MyPlugin
{
    /** @var MyPlugin */
    static $instance;
    static public function bootstrap() {
        if (NULL === self::$instance) {
            self::$instance = new __CLASS__;
        }
        return self::$instance;
    }
    # ...
}

This is a common pattern I use for the base plugin file. The plugin class on the one hand represents the plugin to wordpress and on the other hand it allows to start to use object oriented paradigms for the own code which can even be completely object oriented (but need not be). It’s kind of a controller, interfacing with the whole wordpress API as the request(s).

As the example shows, an instance of the plugin will be created. This allows you to make use of known commons like a Constructor Docs (__construct) to initialize the actual plugin:

# ...
class MyPlugin
{
    # ...
    public function __construct()
    {
        add_filter('the_hook', array($this, 'hook'));
    }

    public function hook()
    {
    }
    # ...
}

At the time the hook is registered, this plugin object already benefits from it’s design: You’ve ceased to hard-code the actual hook function against the concrete plugin classname. That’s possible because of the binding of the class to the object instance for the callback. Sounds complicated, just saying: $this is the plugin. Can be used in hook callbacks, compare Registering Class methods as hook callbacks.

This pattern allows to easier interface with wordpress: the injection is reduced to the names of the hooks and which data they provide. You can then start to implement directly into this plugin class or to refactor your implementation against it, so to only put code into the plugin class that is the bare minimum to define your plugins interface against wordpress, but keep the general logic aside of worpdress. This is where the fun starts and most probably that what each plugin author want’s to achieve in the long run.

So don’t program with worpdress but against it. As worpdress is quite flexible, there is no common or easy to describe interface to program against. A base plugin class can take up this role, allowing you more flexibility for your own code which will lead to easier code and a better performance.

So there is more than just a benefit for name-spacing. Best suggestion I can give is: Try yourself. There is not much you’ll loose, only new things to discover.

You’ll most probably notice differences after you’ve passed some more major updates of wordpress while keeping your plugin compatible.

Caveat: If your plugin directly integrates with wordpress to get the job done, using one or two public functions might suit you better. Take the right tool for the job.

Leave a Comment

tech