Use Classes in your WordPress plugins to increase code portability and reduce name conflicts

One of the most powerful features of WordPress is the huge community of developers making plugins that extend the software far beyond what the core application provides. It also allows people to add just what they want to use, rather than having a single bloated homogeneous download. There are drawbacks as well, of course.

Any time a software package opens itself up to third-party additions, there is a potential for mischief. With WordPress, different plugins can end up stumbling over each other, as each is coded for the core but doesn’t anticipate other plugins. You can also have naming conflicts — when functions or variables in different plugins are given the same name. This is often avoided by adding the plugin name to the beginning of each and every function, variable, constant, etc.

If you have multiple plugins, you probably have a good bit of code that you reuse in all of them. If you’ve been appending the plugin name all along, then any time you update those common functions, you can’t simply copy the new versions over to the other plugins — you have to go over them and update the function names and any internal calls from one function to another.

These problems and others can be avoided by using classes.

By wrapping your plugin’s functions in a PHP class, you gain a number of advantages. You can set plugin-wide variables. You can use common function names and create easily-remembered “wrapper” functions that modify the way common WP functions do things. You can create portable functions that can be copy-pasted into other plugins without any adjustment.

Ready? Let’s get started…

So you have a WordPress plugin. The file looks something like this:

<?php
/*
Plugin Name: My Plugin
...other WP plugin headers
*/

myplugin_function1 () {
	...do stuff...
}

myplugin_function2 () {
	...do stuff...
	$x = myplugin_function1();
	...do more stuff...
}

?>

Step One is going to be to wrap the functions in your new class. When that’s done, you can also get rid of the “myplugin_” starting off the function names, assuming you’ve been doing that. Now we have:

<?php
/*
Plugin Name: My Plugin
...other WP plugin headers
*/

class my_plugin_class {
	function1 () {
		...do stuff...
	}

	function2 () {
		...do stuff...
		$x = function1();
		...do more stuff...
	}
}
?>

Pretty easy so far. Take a look at function2 though. In that function, we call function1 with the code $x = function1();. This won’t work, because function1 is inside the class, and we need to reference that container. That is, when calling a function within a class, we need to reference the class itself. Normally we would do this by prepending the class name, followed by two colons, like so: $x = my_plugin_class::function1().

I just heard half of you throw up your hands. “What good is this? All we’ve done is added a bunch of typing!” Right? Right. So far.

What a class really is in PHP is a model, or template, from which you can create objects. If all you have is the template, then the two-colon method is indeed the only way to get to the functions within. So instead, let’s make something with that template. We’re going to create an object based on that template — a.k.a. declaring an instance of the class. At the bottom of the file, just below the } bracket that ends the class description, we’re going to declare an instance of the class, like so:

$myplugin = new my_plugin_class;

What we’ve basically done here is created a PHP object, contained in the $myplugin variable. That object is modeled off of my_plugin_class, and thus contains within itself all of the functions and variables that are part of that class. The reason this is useful is that now, within that object, we can reference the object itself with a special variable called $this.

Let’s take another look at our plugin:

<?php
/*
Plugin Name: My Plugin
...other WP plugin headers
*/

class my_plugin_class {
	function1 () {
		...do stuff...
	}

	function2 () {
		...do stuff...
		$x = $this->function1();
		...do more stuff...
	}
}
$myplugin = new my_plugin_class;
?>

Here’s where some of that name abstraction I talked about earlier comes into play. The variable $this refers to “whatever object we’re inside right now”. Let’s say function1() and function2() do something useful that I want to use in another plugin. I can copy them wholesale, and paste them into the other plugin’s class, and it will work with no other changes. Back when we started with myplugin_function1(), we couldn?t do that — the function names were specific to the plugin they were part of. As your plugins get bigger and more complex, that can be a big help.

Note: Of course you can still call any of these functions from outside the object if you need to Just call the object by name instead of “$this”. For example: $myplugin->function1().

If for some reason you ever need to change the class name or the name of the object, (for example, they conflict with another plugin), you’ll likely only have to change one or two lines, instead of changing a bunch of function names. (Real-world example — I’ve done work on a plugin called “Quiz”, which had, as it’s function prefix, “quiz_”. I can easily imagine somebody else coming up with a plugin using that same name — so the first thing I did was to put it all in a class. Down the road it will be quite simple to change that if needed.

You can also make class variables. These are kind of like globals, but they’re only “global” to the class that they’re part of, and within class functions, you don’t need a “global” declaration to use them. This is perfect for plugins, as you’re certainly not going to be creating any variables that are called by core. For example:

class my_plugin_class {
	var $x;
	function x_inc() {
		return $this->x + 1;
	}
}
$myplugin = new my_plugin_class;

As with functions, you can call a class variable outside an object with $myplugin->x.

That’s all there is to it, really. Classes are a big topic — whole books have been written on object-oriented programming — but for the purposes of most WordPress plugins, this is all you need to know.

[Update: Okay, one more thing: If there is a function within a class that has the same name as the class, it will run automatically when an instance is declared. That is, a function called (for example) my_plugin_class(), if present, will run automatically; and is therefore a very good place to put your add_action hooks and other such calls to the system. For more info, read up on PHP “constructors”.]

I use this technique in all my plugins, and it has allowed me to abstract out a lot of common functionality that I can move from one plugin to another simply with a copy/paste, without having to worry about digging through and renaming all the internal function calls. Throw in a few class variables, and the code becomes quite flexible and truly portable.

Next Time: Make it simple for template designers to use your custom function, by using do_action()

Previously: Consolidate Options with Arrays in your WordPress Plugins

This entry was posted in Codecraft, Webcraft and tagged , , , , , , . Bookmark the permalink.

16 Responses to Use Classes in your WordPress plugins to increase code portability and reduce name conflicts

  1. AskApache says:

    Stephen,

    Wow! I recently found your site and really want to thank you for such great information. A lot of the info out there just plain sucks, almost everything on your site I’ve read so far has been a best-practice, you know what your talking about.

    I’m currently converting the Password Protection plugin to a class, thanks for the inspiration and keep the amazing tips coming!

  2. Pingback: Use Classes in your WordPress plugins to increase code portability and reduce name conflicts ? Nerdaphernalia | My Web Development Bookmarks

  3. Pingback: Use Custom Actions in Your WordPress Plugins – Nerdaphernalia

  4. Pingback: Wordpress plugins don’t commonly use classes, why? | HagelBlog

  5. Dan says:

    Looking at this it looks like a class is the right choice for most plugin. Is there a reason why I wouldn’t want to use a class?

  6. Pingback: How to Call Class Functions in Wordpress Templates - Derry Birkett

  7. Pingback: Wordpress, Plugin, Class, Programmation orientée objet - Créer un plugin Wordpress avec des Class selon des principes de programmation orientée objet | Réseau social des créateurs de site web

  8. Pingback: Organising WordPress plugin/theme code: Part 2 | Wordpress & Bacon

  9. Castle says:

    I cannot believe that an article from 2008 is so far my best read about WP OOP!

    I’m just starting PHP OOP and for me is quite confuse. But your article helped me a lot.

    Please write more about this topic!

    All the best

  10. Aldemar Calazans Filho says:

    I recently developed a very simple plugin and tried the first method (without declaring an instance of the class) to call my functions inside a class:

    name_of_the_class::name_of_the_function();

    It worked well. I was having dificulties to wrap my function inside a class and after reading your article, my problem was solved.
    But I also noticed that, in PHP 5.4, this first method, exactly as described, is considered a “strict standard” deviation, unless you declare your functions as “static”.. So, I guess a better example for the first method, according to the strict standards, would be:


    class my_plugin_class {
    public static function1 () {
    ...do stuff...
    }

    public static function2 () {
    ...do stuff...
    $x = my_plugin_class::function1();
    ...do more stuff...
    }
    }

    Note: these strict standard warnings appear only if you have you php.ini file configured to display all sort of errors (in a development environment, for example).

    • Aldemar Calazans Filho says:

      Probably, in 2008 (with an older version of PHP) these way of writing the code was considered strictly correct … 🙂

    • Stephen R says:

      Aldemar: using the classname::function() syntax eliminates the ability to easily reuse code, because the class name is hard-coded throughout. It’s better to use $this->function() if you want portability. (Otherwise you might as well skip the class altogether and just Prefix_ all your functions….)

      • Stephen R says:

        I would also point out that WordPress minimum requirements are PHP 5.2.4, not 5.4. Not important if you’re just programming for your own site, but worth keeping in mind for a publicly released plugin.

        Also, as of PHP 5.3 there is actual Namespace functionality — meaning we shouldn’t have to keep “faking it” with classes.

  11. Jonas Maro says:

    And what about this…

    You create your own php classes framework for your plugins in WordPress. Then, you create a plugin and publish it. Later, you optimize your php framework and add new functionalities to your existing classes. Then, you create a second plugin and publish it.

    What happen if a person has installed both plugins and they ask to require or include those same classes? I think it will generate a redeclaration error.

    In case of asking for class existing previous class loading, what if WP has already load the class for the first plugin but it is the old version. The plugin with the newest version will ask for new functions that are not include in the old and loaded one.

    These are my doubts. How can I manage with this?

Leave a Reply

Your email address will not be published.