Fatal Error Cannot Redeclare Class

Fixing the "Cannot redeclare class" PHP error


In the previous article, we used code like this to prevent collisions between function names:

include MODX_CORE_PATH . 'components/mycomponent/model/mymathfunctions.class.php';

$math = new MyMathFunctions();
echo $math->addIntegers(2,3);
/* Displays 5 */

The problem with this code is that if it's called more than once on a page, the include statement will cause PHP to throw a fatal error when it sees the class code for the second time. The functions are no longer colliding, but the class declaration is. The error message looks like this:

Fatal error: Cannot redeclare class MyMathFunctions
    in somepath/mymathfunctions.class.php on line 7

In this article, we'll see how to prevent that error.


Solutions

The easiest way to prevent this error is by changing the include statement:

include_once MODX_CORE_PATH . 'components/mycomponent/model/mymathfunctions.class.php';

We've changed include to include_once. Now, when PHP encounters the include statement, it will check to see if it has already included the file. If it has, it will skip the include operation and no error will be thrown. The down side of this method is that it takes time for PHP to do the check. In modern versions of PHP on modern servers, though, the time is only about 1 or 2 millionths of a second.


Another option is to use include, but only if the class is not already loaded. That would look like this:

if (! class_exists('MyMathFunctions')) {
    include MODX_CORE_PATH . 'components/mycomponent/model/mymathfunctions.class.php';
}

A third option is to use include, but wrap the class itself in if (! class_exists() ) {}. With our class, that would look like this:

if (! class_exists('MyMathFunctions')) {
    class MyMathFunctions {
        function addIntegers($a, $b) {
            return $a + $b;
        }
    }
}

Autoloading

Yet another option for solving this problem involves using an autoloader. When you register an autoloader, you never user include or require, except to include the autoloader code. With an autoloader in place, PHP will automatically load any class that isn't already loaded. That solution is beyond the scope of this article because it's not a practical way of solving the "Cannot redeclare class" error in someone else's code. We'll discuss autoloading in a future article.

Fixing Things

If you run into the "Cannot redeclare class" error with a MODX extra (or your own code), you can fix it yourself by using any of the three methods above. The speed differences between the methods are fairly trivial, so use whichever method is easiest to implement for your use case.


Coming Up

Instead of include or include_once, you can also use require or require_once. The problem with the require twins is that if the file isn't found, PHP will throw a fatal error. If the user has turned off the display of PHP errors, site visitors may be looking a the white screen of death when the required file isn't found. If errors are displayed, the visitor will be looking at an ugly PHP fatal error message. Neither condition is a very graceful way of handling errors. We'll see another way to handle this situation in the next article.



Comments (0)


Please login to comment.

  (Login)