There is a way to use CLASS_EXISTS and __autoload without CRASH the script?

CRISHK Corporation picture CRISHK Corporation · Sep 28, 2010 · Viewed 11.8k times · Source

Example:

ClassName.php

<?php echo "This will crash all"; ?>

In another file...

foreach ($FILENAMES_WITHOUT_DOT_PHP as $name => $value) {
    if (class_exists( $value )) {
      echo "ClassName exists...";
    }
    else {
      echo "ClassName doesn't exists....";
    }
}

The output of this code is: This will crash all

Instead of this: ClassName doesn't exists....

Autoload function:

function __autoload( $var_class )
{
     require_once( "$var_class.php") ;
}

Answer

ircmaxell picture ircmaxell · Sep 28, 2010

Ok, so here's how it works internally.

When you try to use a class that doesn't exist, it calls each one of the spl_autoload callbacks one by one until the class exists (and the __autoload function is one of them). If it doesn't exist at the end of the chain, it raises the class not found error.

When you call class_exists without the second parameter (which tells it not to try to load it if it doesn't exist), it calls the chain of spl_autoload callbacks until either it finds the class, or the last method is called. Then it returns if it found the class.

So it all depends on what you are doing in the autoload function. If you do something like:

function __autoload($class) {
    $filename = PATH_TO_CLASSES . $class . '.php';
    if (!file_exists($class)) {
        die('Could not find '.$class);
    }
    require_once $filename;
}

It will kill execution and it won't work as intended. Instead, you should do:

function __autoload($class) {
    $filename = PATH_TO_CLASSES . $class . '.php';
    if (file_exists($class)) {
        require_once $filename;
    }
}

That's all you need to do.

Now, you don't want the file to be executed. That's fine. There's an easy solution to that. Don't put that file into the same directory as your autoloaded classes. It defeats the purpose of autoloading.

The only other solution would be to store a map of class names to file names, and base your autoloading off of that. Otherwise it would always execute the file (since that's what you're asking it to do)...