Using instanceof in MODX 2 and 3

A safe way to use instanceof in programs that will run in both MODX 2 and MODX 3.

By Bob Ray  |  December 9, 2025  |  5 min read
Using instanceof in MODX 2 and 3

In a previous series I wrote about creating extras that will run in both MODX 2 and MODX 3 without throwing deprecation errors. In that series, I recommended getting rid of any uses of PHP's instanceof operator . I recently stumbled on a simple, but relatively undocumented solution (actually two solutions), that allow you to use instanceof in both versions.

The Problem

The class names in MODX 3 are "namespaced." So, for example, the traditional modResource class is modResource in MODX 2, but MODX\Revolution\modResource in MODX 3. If you use the MODX 2 class name in MODX 3, you'll get a deprecation notice unless you have the log_deprecated System Setting set to "No." Even if the System Setting is off, the program will be slowed down slightly while MODX checks the System Setting to see if it should log the error.

What Version is this?

Before we can create code that handles the current version we need to determine the version the code is running in. Here's the easiest way to do that:

$versionData = $modx->getVersionData();
if ($versionData['version'] >= 3) {
    $isModx3 = true;
} else {
    $isModx3 = false;
}

PHP doesn't mind if you run things together, so we can reduce the code above to a single line:

$isModx3 = $modx->getVersionData()['version'] >= 3;

The line above will always set $isModx3 to false in MODX 2 and true in MODX 3 or beyond.

The getVersionData() method of the $modx object returns an associative array that describes the version. All we need from that array is its 'version' member, which will contain the current major version (2 or 3). Notice that we've used >= instead of = to allow for future versions of MODX, which will almost certainly use namespaces.

For the code below, assume that the $isModx3 variable has been set correctly above the code. I should mention that this all assumes that the $modx variable is already set to the modX object. This is done automatically in any snippet or plugin. To run the code outside of MODX, you would need to either instantiate the modX object yourself or get the version from the core/docs/version.inc.php file.

All the code below assumes that both $modx and $isModx3 have been set properly.

Solutions that Don't Work

This code looks like it might work:

if ($isModx3) {
    use MODX\Revolution\modResource;
}

Unfortunately, if you try that, you'll see this error:

PHP Parse error:  syntax error, unexpected token "use"

PhpStorm flags the code above as an error, with the helpful message: "the 'use' keyword must be declared in the outermost scope of a file." So, a conditional use statement isn't going to work.

Here's another method that looks like it might work to let us use instanceof in both versions:

$prefix = $isModx3 ? 'MODX\Revolution\\' : '';

if ($doc instanceof $prefix . 'modResource') {
}

Not only does the code above not work, it fails in a particularly dangerous way. The if statement is always true, no matter what the values are. It reports that the variable is an instance of the class whether it is or not!

If you're skeptical, you can try this code in a snippet:

$prefix = 'asdas';
if ($modx instanceof $prefix . "zxczx") {
    echo "Yes";
} else {
    echo "No";
}

The code above will report "Yes" no matter what the prefix or class name are set to.

Things that Work:

One solution is to use a variable as the class name being tested by instanceof:

$prefix = $isModx3 ? 'MODX\Revolution\\' : "";
$class = $prefix . 'modResource';
if ($doc instanceof $class) {
}

This works because instanceof sees the full name of the class, but it's a little cumbersome. There's actually a faster and easier way:

$prefix = $isModx3 ? 'MODX\Revolution\\' : "";

if ($doc instanceof ($prefix . 'modResource')) {
}

Notice the extra set of parentheses around the concatenated string ($prefix . 'modResource). This makes instanceof look at the full class name. It solves the problem with less code. And the code is actually faster and more efficient because PHP doesn't have to set the value of an extra variable.

The method you use is up to you. The second method is faster and easier, but there is a chance that, sooner or later, you'll forget the extra parentheses. Doing so could cause problems that might be serious, and that would be very difficult to debug.

In the examples above, we used the modResource object as an example, but the prefix we created will work for almost all MODX objects (including the modX object itself). Exceptions include Media Sources, Transport Package objects, and the Mail object.


Bob Ray is the author of the MODX: The Official Guide and dozens of MODX Extras including QuickEmail, NewsPublisher, SiteCheck, GoRevo, Personalize, EZfaq, MyComponent and many more. His website is Bob’s Guides. It not only includes a plethora of MODX tutorials but there are some really great bread recipes there, as well.