Agile Programming with PHP, Part 1: Including Class Files
Over the past several months I’ve been following Agile coding principles in my work, as described by Bob Martin and others (see, for example, Clean Code, Agile Software Development, and Growing Object-Oriented Software, Guided by Tests). Applying these principles in PHP presents some challenges. This is the first in a series of posts on how I’m dealing with them. My Google searches about PHP and Agile coding don’t turn up much, so I figure I can break some new ground 😉 . But I don’t consider myself an expert – feedback is welcome.
If you follow the Agile principle of small methods and small classes, your projects will consist of a large number of small files. In Java, this doesn’t matter much – the project is compiled before it’s deployed. But PHP is a scripting language, so it’s compiled on the fly. include
and require
statements can have a moderately expensive performance cost (see here and here). So what’s the best way to include your files efficiently?
require_once
vs require
I always use require_once
to include a required file. I don’t use include
, which allows the compilation to proceed even if the file is not found (a class file isn’t going to be optional). require_once
has a reputation for being slower than require
, but this benchmarking indicates otherwise (I wouldn’t consider that an exhaustive study, but it’s enough that I’m not going to lose sleep over it). This way I don’t have to worry if a file has been included somewhere else already. If you have lots of small classes, used in various places, require_once
can save you from that headache.
Where to put your require_once
calls
The simplest option, and worst from a performance perspective, is to include all your project’s class files in the initializing script. Any given execution path through your project likely only requires a subset of your classes. Loading up all of them for every single http request is unnecessary and may impact performance. It’s also problematic in that dependencies between classes are not evident to someone reading your code. That is, if you tried to use one of the classes in a different project, and that class has dependencies on other classes, the class would fail to compile.
A second option is to include all the class files a given class depends on at the top of that class file (before the class
line). This is better, and in PHP code I’ve seen by others, it seems to be a fairly standard practice. It’s also good to see all the dependencies clearly stated at the top of the class file.
A third option is what I’ve been doing, which is to put my require_once
statement for a class file on the line before I call new
on that class. For example:
class Shashin { .... public function validateShortcode($shortcode) { require_once('Shortcode/ShashinShortcodeValidator.php'); $validator = new ShashinShortcodeValidator($shortcode); $validatorResult = $validator->run(); .... } .... }
I used to think this approach would cause PHP to think the included class was a child of the function where it was included, but that is not the case. The class is simply read and put into memory.
The potential downside of this approach is that you have to read through the file to see the dependencies, but so far I haven’t had a problem with that, because my classes are small 😉 . I like it because I’m making PHP hit the filesystem only when necessary – you don’t always need every possible dependent class for every execution path through a given class. Sometimes there is a trade-off between code readability and performance, but in this case, the impact on readability feels trivial.
In the case of Shashin (my WordPress plugin I’m currently updating), I have a main class where the various WordPress hooks are invoked (which in my experience is the only rational way to deal with WordPress). Therefore, that main class acts as a controller for the application, and ends up including almost all the other classes at some point, from within its various methods. So I do not want to just include them all at the top of the file, as only a handful are needed for any given hook.
The one case where I do include a dependent class at the top of a class file, is when it is a concrete class implementing an abstract class (or interface). I’ll include the abstract class at the top of the concrete class. There’s no reason to make the caller of the concrete class keep track of the dependency on the abstract class.
Lastly, if you do have performance problems, file includes are probably not the first place to look. Database queries are the more common culprit. But if you do need to reduce your hits on the filesystem, you should look at opcode cachers, such as APC before you contemplate writing hard to read and maintain God objects.
I think it is a mistake to burry your imports (I’ll stick with Python terminology, thanks) like you’ve chosen to do. I prepose that optimizing for humans is more agile than worrying about file system calls. They should be at the top of each file. The way you’ve done it is an example of premature optimization. I still love you.
Thanks John. It may have been better if I titled the post “Agile Programming with WordPress” instead of just PHP generically. If this were for a project at work, where I know the server environment and the usage environment, I’d fully agree with you. But for a WordPress plugin, I cringe at the thought of my main controller class having 30 or more includes at the top, when any given call will only need a handful of them. Since it’s a plugin with thousands of users, on a wide range of server and usage environments, it draws me into doing what I’d call “defensive optimization.” I’ve become a huge fan of the code readability philosophy behind Agile. In this case I didn’t feel that I was sacrificing much in that regard, for the sake of possibly saving myself some hard to diagnose support requests.