I’m writing a WordPress plugin. (However, this is not a WordPress-specific question – this challenge could arise in any PHP codebase which uses a plugin pattern.)
My plugin makes use of a popular third-party library, which is also used by a lot of other common WordPress plugins.
Obviously, if both my plugin and another plugin load their own copies of this library, PHP is going to throw an error, because I’m trying to redeclare an already-declared class.
How can I avoid this conflict? Before you answer, please consider why I’ve rejected these obvious options:
-
I could rename the library’s classes, or put them in a new namespace. I don’t like this because it involves modifying the library files. If I later need to upgrade to a newer version of the library, it would overwrite my modifications. And it’s just generally an inelegant PITA.
-
Before my plugin actually includes the library, I could use
class_exists()
to make sure it hasn’t already been included. There are two reasons I don’t like this option:- Another plugin might use a different version of the library that has a slightly different API. This could cause my plugin, or the other plugin, to break (depending on which version of the library gets loaded first).
- More importantly: the library in question contains multiple class definition files, and each child class includes its parent. Say that my plugin includes ChildClass1.php (which, in turn, includes BaseClass.php), and another plugin includes ChildClass2.php (which also includes its own copy of BaseClass.php).
class_exists()
doesn’t help me here – there’s no way that both plugins can include the ChildClasses they need without causing a conflict.
So: how can I make use of this library without running into one of these problems? Is there some way to override the library’s namespace at include time (without modifying the library)? Is there some other solution that I’m overlooking? Seems like this must be a pretty common situation.
I’m answering my own question. (I can’t believe I was this naïve only three years ago!)
This problem (among others) is exactly why dependency managers exist. (If you use npm, then you’re already familiar with dependency management.)
In the PHP world, Composer is the standard tool for dependency management.
However, WordPress isn’t really built to play nice with dependency managers (or with source control). In fact, WordPress actively fights against these practices.
There is a project called Bedrock, which tries to contort WordPress into something that’s compatible with modern development practices. I haven’t used it â but if you must use WordPress, it’s worth investigating.
tl;dr: