One of the easiest things that we can do when working on WordPress plugins is to drop require_once or include_once statements throughout our code.
And why not? It’s an easy way to bring in all of the necessary files or dependencies for a given class, have it easily readable, and not have to worry about creating huge files of code. That is, it helps us simplify what we’re writing so that we’re able to have our classes [mostly or ideally] do what they are doing well.
If you’ve read this site for the past year or so, though, you know that I’m a fan of autoloading and it’s something that I think anyone working with PHP – regardless of if you’re using WordPress or another platform – should use.
But it raises two questions especially if you’re just starting out:
- Why bother with autoloading when there are other ways to handle loading dependencies?
- How does autoloading stack up against compiled languages?
So I thought it would be worth answering this in the next couple of posts.
Why Bother With Autoloading?
The short of it is this:
- require_once and include_once can lead to code that’s hard to debug,
- it’s difficult to trace code.
But how so?
1. Debugging is Hard
When writing code, if anything is certain, it’s that there will be something that doesn’t work as intended. It’s in the nature of what we do, right?
So when it comes times to debug code, we all have our strategies.
- some of us opt to use echo or var_dump to trace code,
- use a plugin in WordPress,
- others use a debugger.
Though this post is not about how to debug it is the fact that we have to debug. So if we know we’re going to have to do it, shouldn’t we make it as easy on ourselves as possible?
PHP is a dynamically typed language, so there’s a lot of stuff, in general, that’s taken care of for us whenever we’re writing the code. That is, certain things are inferred or coerced whenever the code is run.
For example, assume you’re working with a string, and you’re comparing it to a number. The interpreter will do what it can to guess what it is you’re doing (are you looking to parse the string to an integer or vice versa?) and then work with that.
Working with variables alone can be an exercise in precision because we want our code to read as we intend. Why leave it up to the interpreter to guess what it is that we mean? And if the interpreter has to do extra work, humans certainly do.
To that end, if we know that bugs are going to be introduced and we know there are ways to write cleaner code, why wouldn’t we do it?
2. Tracing is Hard (Or Maybe Harder?)
But this still doesn’t provide a reason as to why we should rely on something like an autoloader versus built-in facilities of the language, does it?
Consider this: Say you’re looking through a file trying to find a bug and you come across a function that has some code, uses include_once, then uses some other code.
This means you have to read the code, keep this mentally filed, hop into another file, understand that code, then return to the original file. And this assumes the second file doesn’t include or require other files, either.
With that said, you can see the predicament this introduces when you opt to nest this code throughout the rest of your program. In short, you’ve nested the inclusion of dependencies which inherently makes it more difficult to track where something may be going wrong.
This isn’t to say that autoloading automatically fixes this, but it is to say that it doesn’t have to be like this. Instead, you can write code that instantiates classes, calls methods, and then executes code without the need to include anything manually.
More Readable, Traceable Code
In doing this, I find that it forces us to write cleaner code, arguably more maintainable code. It also makes it easier to write code that we can more easily trace, and that’s easier to leverage with a debugger.
That is, we can set breakpoints in certain places in our code, have the debugger automatically take us into the class that’s being invoked, and step back out into the function that was calling it.
This doesn’t mean it can’t be done any other way, but the benefits far outweigh the alternatives. And, of course, this still leaves the question of why autoloading (or any inclusion of third-party files) is needed at all.
But that’s what will be covered in the second part of the series.
My post on Namespaces and Autoloading in WordPress, as well as the Simple Autoloader for WordPress, are two other resources I obviously find related to this particular post. So if you have the time, check ’em out (and don’t hesitate to open an issue or a pull request on the simple autoloader project).