Using Objects with WordPress Plugins, part 1Filed Under: plugins
I’ve decided to kick of 2008 with a series on using object oriented PHP for WordPress plugins. I intend this to be a ground up look at using objects and so I will start at the beginning.
A lot of people come to WordPress before they come to PHP. They learn how to use tags, then how to use snippets of PHP in their themes, and then start to look at plugins. My re-introduction to PHP after several years happened just this way.
My plugin development went through three distinct phases: Classless, Static, and Object Based, the latter only when I started to look seriously at the best way to structure my plugins.
In this first part of the series I am going to look at each of these stages; the aim is to ensure that anyone reading this is at stage three, before I continue with the series.
Classless Plugins
Classless plugins are the first step in the ladder. At their simplest they are one command and one function. I have also included in the example a function designed to output content as a theme tag:
add_filter( 'the_content' , 'modify_content' ); function modify_content( $content ){ return $content . '<p>An extra bit of content</p>'; } function ouput_something_to_theme(){ echo 'something'; } //in the theme we can call any functions we like directly output_something_to_theme();
This will do the job just as well as the most complex structure, but it has one major weakness: It has a very high risk of naming collisions; i.e. if these functions have the same name as functions from WordPress itself, or from another plugin then the result will be a list of errors.
This is actually quite likely as many plugins do similar tasks, such as alter content.
Static
The second stage exists purely to combat the problem of naming collisions. The page in the WordPress Codex about this was my first introduction to classes in PHP.
To combat the problem the functions are wrapped in a class and accessed statically. The functions can then be named anything without fear of conflict
class my_plugin_class { function modify_content( $content ){ return $content . '<p>An extra bit of content</p>'; } function ouput_something_to_theme(){ echo 'something'; } } //when we add the filter we now need to include an array to tell it which class the function is in. add_filter( 'the_content' , array( 'my_plugin_class' , 'modify_content' ) ); //in the theme a scope resolution operator would need to be used my_plugin_class::output_something_to_theme();
There is still a minor problem of naming collisions, but it is reduced as much as it can be.
This method works and for simple plugins, like the example, perhaps there is no need to go any further than this. This is still very much a half-way house though. It introduces the class structure without making use of the benefits, and that is where stage 3, Object Based Plugins, comes in.
Object Based
At this stage, I think it is a good idea if I explain a little about objects before showing how this applies to WordPress. If you are ahead of the game at this point you may wish to skip this bit
What are objects?
In programming terms an object is a construct that contains both state and behaviour; i.e. it contains data, like a variable, but can manipulate its own data if you ask it to.
The easiest way to understand objects is to think of them in terms of real world things; first you start with the concept. I am going to use the idea of a train.
You know what a train is: it has at least four wheels, has an engine of some kind, and pulls carriages. This our basic train concept. If we see a train we can compare it to this concept to decide whether it is in fact a train.
We will call this concept a ‘class’ and our class is called ‘train’.
If we were standing on the platform wanting to go somewhere though, this class, ‘train’, is not going to help; it isn’t real, it is just an idea. So we need to make an actual train ourselves.
What we need to do is to use our class as a blueprint and construct our object according to the class. My Train, that we have created, is an object of type (or class) ‘train’
Once we have created the object we can now do with it what we want. We can repaint it, change its name, or instruct it to pull carriages.
In PHP terms we have done this:
class train{ var $wheels = 4; var $colour = 'red'; function pull_carriages( $distance ){ //do something return 'pulled' . $distance . 'miles'; } } var $my_train = new train(); $my_train->colour = 'green'; echo $my_train->pull_carriages( 5 );
This isn’t a tutorial on object oriented programming so I won’t go any further than that. A quick search will find your hundreds of websites with good tutorials, most of which I am sure are better than any I would write. I encourage you to read at least one or two if you feeling at all out of your depth at this point.
Using objects
Instantiating the classes into objects brings a number of benefits. The plugin can maintain its own state, including getting database information just once, instead of once for each function, and access it with the $this keyword. It can set this state up, and register itself with all the necessary WordPress hooks when the object is created, making it self contained, and it also helps to make the code more maintainable.
class my_plugin_class { var $message = ''; //the contructor (php4 style) function my_plugin_class( $message ){ add_filter( 'the_content' , array( &$this , 'modify_content' ) ); $this->message = $message; } function modify_content( $content ){ return $content . '<p>An extra bit of content</p>'; } function ouput_something_to_theme(){ echo $this->message; } } //we now need to instantiate the class $my_plugin = new my_plugin_class( 'Something' ); //in the theme we would access the object method directly. $my_plugin->output_something_to_theme();
This is a very simple example, but it shows the basic structure of an object based plugin. The more complex the plugin becomes the clearer the benefits of using object based plugins are.
What now?
In the next part of this series I will look at using secondary objects to simplify some of the basic tasks, keep to the DRY principle (Don’t Repeat Yourself) and move the code outside of the actual plugin object.
- Permalink
- Andrew Rickmann
- 1 Jan 2008 12:00 AM
- Comments (0)