If you write object-oriented code for WordPress (usually within the context of plugins), you’re likely to come across a class_exists check before initializing a class. But we should start avoiding class_exists in much of our code at this point (with a few exceptions that I’ll outline below).
Depending on the version of PHP you’re using, this makes sense. Or it did at one time. As of PHP 5.3.0, this isn’t necessary. Instead, it’s a better practice to use namespaces.
Avoiding class_exists
You can see all of the requirements for various versions of WordPress on this page so if you’re working with legacy versions of WordPress then the whole class_exists check might be worth it.
Still, there’s an important note:
Note: If you are in a legacy environment where you only have older PHP or MySQL versions, WordPress also works with PHP 5.2.4+ and MySQL 5.0+, but these versions have reached official End Of Life and as such may expose your site to security vulnerabilities.
But for most of us, modern hosting environments support at least PHP 5.3.0, if not higher, and because of that, we don’t have to use class_exists.
That said, it’s not uncommon to see something like this:
Or like this:
Years ago, I’d write code like this, as well. Sometimes it was to interface with a pre-existing codebase. Other times, it was because I didn’t know any better. The thing is, this has become something that we see in WordPress-based code when we don’t have to use it.
In fact, I’d argue that we shouldn’t be using it anymore.
But the more code you write and the more code you read, the more you learn, right? That’s part of the whole reason for namespaces and autoloading.
So how would the code above be written?
Maybe like this:
Still, this raises the question for some: How do namespaces help in place of using class_exists?
Ideally, if the same class exists within a namespace, then there’s a problem with the namespace. Remember that you can think of a namespace like a package made up of unique pieces. And because they are unique, there should never be another piece or, in this class, another class just like it.
To that end, rather than using class_exists checks, aim to use namespaces. Of course, I’m not saying go back and refactor all of your code – I’ve not done that – but that doesn’t mean the code I write or review include the use of or recommendations for.
It’s an easy change that can go a long way regarding keeping code easier to read, littered with fewer conditionals (a post for another time), and keeping it far more organized.
Great and useful article as usually.
If may I, removing the if statement make the file psr compliant.
link: http://www.php-fig.org/psr/psr-1/#23-side-effects
This help us to keep files simple and coherent across the project.
I suspect this practice came about as a result of plugin files being loaded more than once. That can happen in a variety of scenarios, and results in a fatal error:
Fatal error: Cannot redeclare class
It can be difficult to determine why a file is being loaded multiple times and to correct the root cause, but it’s easy to add a
class_exists()
check, so that became a standard practice.I think it is also worth mentioning a good use of
class_exists()
is when using someone else’s class.if ( ! class_exists( 'ClassFromAnotherPlugin' ) ) {
return;
}
$instance = new ClassFromAnotherPlugin();
// Do my own custom things with $instance here.
You need to use class_exists when using a class from a plugin in your child theme as seen here in the latest Genesis child theme
if ( ! class_exists( ‘WooCommerce’ ) ) {
return;
}
One scenerio where it can be handy is feature detection. Say your plugin rely on WooCommerce being loaded. Checking if the WooCommerce class exist solve the problem.
I completely agree with you on avoiding class_exist. Rather namespace the class to be unique to your plugin. This is exactly what i do with EDD_SL_Updater class in my plugins.
What’s your reaction to plugins that defines a class and instantiate the class in same file? I feel this is wrong and all instantiate of a class should be done outside the file that declares it. Thought?