Writing Plugins: Writing Maintainable Procedural Plugins
- Don’t use Globals.
Okay, so WordPress uses globals and that is okay, so why can’t you use globals? If you know what you are doing then by all means, ignore this suggestion, because this does not apply to you. For all of the others, the suggestion to put logic in functions applies.
If you place variables in main(), then they automatically become global to the execution process. If you don’t use naming convention practice, then your global variable could clash with another plugin.
It is not that you shouldn’t use globals, with procedural programming, there is no way around using globals. However, declare and set the globals up in functions, instead of setting them at the top of the plugin execution path.
- Use naming conventions
And whatever you do, don’t start your functions with “wp_”. Choose a function prefix that no one (that you know of) uses yet, which could be your company or your name (although, it just doesn’t seem right to start functions using human names, since author information is better located elsewhere), the plugin name, or something you just make up.
As long as you use it throughout the plugin, call it whatever. Consistency is key, and with naming conventions and coding standards, no one can tell you that you are wrong, as long as you are consistent. Most developers do conform to the WordPress coding standards, but use whatever naming convention pleases you.
- Split duplicated logic into functions.
Are you writing the same lines of code, over and over again? How about you split that chunk of code into its own function and call that function in different places. The goal is to only write code once and reuse it in many different locations.
This also allows you to fix a bug in one location and not have to track where similar lines of code is located. It saves time, reduces the chances of defects, and increases the maintainability of the code. Also, since most of the time, when code is split it usually increases the ability of others to grasp the full purpose of one of your functions.
For completeness, it will be pointed out, that by splitting logic into functions does increase the overhead (where opcode caching is not used), so it will decrease the performance of your plugin. Not by much, however, it is something to look at when optimizing and is a counter suggestion to this suggestion for optimization.
However, the optimization arguments, that I’ve seen have not convinced me that the sacrifice of maintainability and clarity is worth a few milliseconds (if even that). If your plugin is hurting, it is most likely not, because you one or two large functions into four or five smaller ones.
- Keep the branches and functions to a minimum
I’ve seen plugins where there were foreach loops within if statements within foreach loops within if statements. Besides optimization complaints, I would probably say that the function needs to be simplified somewhere, so that someone like me would even want to read it to understand what it was trying to do.
There are metrics that will inform you of how difficult a function or method is, but any function more than 25 lines is pushing the barrier of complexity. The other index for branches, is a little bit more difficult to recommend. However, try not to have more than 5 branches or like the above example. Most of the time, something like that can be split into its own function and called, if only for the sake of sanity when reading through the function.
By keeping the complexity of functions to a minimum you increase the chances of a user coming and finding an issue and making a modification that won’t break anything. You also increase the odds that you won’t create something so complex that even you don’t understand what is happening, “Yeah, it works, just don’t breath on it!” Statements like that, should be avoided, because something will break, and you won’t be able to fix it.
- Keep the base plugin file length short.
Again, this recommendation is arguable, so you can choose to have all of your functions in one file or split them into multiple logically named files. It is up to you. The argument for why you should keep functions in a single file is for optimization and there is enough optimization evidence for having PHP functionality in one file. However, I believe in maintainability, and I don’t like scrolling up and down in one massive file.
My recommendation is that when your plugin becomes large enough, that you split it into logical portions. Usually, what I will see for classes, is a block that checks for whether the class exists and if not then it will define the class. I think just having the class in its own file and using require_once() makes more sense. You gain nothing in optimization over require_once(), because opcode caching won’t cache the class until it knows it needs it and the if statement will prevent it from doing so.
My base plugin usually only have the activation, deactivation, and init hooks and everything else is in other files. I also split my administration files into their own files separate from other plugin functionality.
- Have HTML, place them in their own template file.
I admit I do place HTML into functions myself, as it is quick and easy method. I think placing HTML in functions is not hackish or dirty at all, since it is practically the same as placing them in its own file.
Where I don’t do this, is for administration HTML, because it is much bigger than a snippet of HTML and requires other actions. You must protect your administration files, so test for ABSPATH before outputting HTML.
No comments yet.