12

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") ;
}
durron597
  • 31,968
  • 17
  • 99
  • 158
CRISHK Corporation
  • 2,948
  • 6
  • 37
  • 52
  • obviusly is necessary to use autoload because the class isn't loaded! – CRISHK Corporation Sep 28 '10 at 12:53
  • Show your autoload function... It should show `ClassName doesn't exists....` after the `This will crash all`, since it doesn't care by default if the class is not loaded. I suspect you're killing the execution in the `__autoload` function if you don't find the class, and you shouldn't be... – ircmaxell Sep 28 '10 at 13:00
  • From the code that is given the results can't be reproduced. So post some more code. – tplaner Sep 28 '10 at 13:02
  • __autoload function is any function that loads the class and it works properly. The problem is when it finds files that have execution codes for any reason, as in the example – CRISHK Corporation Sep 28 '10 at 13:06
  • What I'm trying to do is to know what strings are classes or not of a list of FILENAMES. – CRISHK Corporation Sep 28 '10 at 13:08
  • No, show your function. By default PHP does not behave how you describe (>= 5.2 at least). So the cause is more than likely in your code. So if you show your code, we may be able to help. Otherwise it's all just a shot in the dark... – ircmaxell Sep 28 '10 at 13:08

4 Answers4

14

Using class_exists will hit the autoloader by default which is why you're seeing your issue. You can bypass the registered autoloader by setting the second param to false.

class_exists('foo', false)

From PHP Documentation

Brian Fegter
  • 693
  • 12
  • 21
12

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)...

ircmaxell
  • 163,128
  • 34
  • 264
  • 314
1

Use class_exists inside the autoload function, then don't ever use it again. That's the point of the autoloader.

class App {
    static private $_instance = NULL;

    public function __construct() {
        spl_autoload_register('app::autoLoader');
    }

    public function __destruct() {
    }

    public static function getInstance() {
        if(self::$_instance == NULL) {
            self::$_instance = new App();
        }
        return self::$_instance;
    }

    public static function autoLoader($class) {
        $className = stripslashes($class);
        if (class_exists($className)) {
            return;
        }
        require $className.'.class.php';
    }
}
AutoSponge
  • 1,444
  • 10
  • 7
  • 6
    HUH? No it isn't... There are plenty of uses for class_exists. One of which is to see if the class is loadable to begin with (to see if it's available). Besides, there's no reason to call `class_exists` from within the autoload function since you know it doesn't already (unless someone calls it manually, but they shouldn't anyway). Oh, and if I were you, I'd do some checking to determine if the file actually exists before just doing a blind `require` on it. Otherwise you lose the ability to check to see if a class is loadable (which can come in handy for adapters, etc)... – ircmaxell Sep 28 '10 at 13:07
  • In my example, all class files are in the same directory. But yes, file check is a good idea. – AutoSponge Sep 28 '10 at 13:22
0

What happens is quite logical. Your __autoload function is probably just including ClassName.php, so it will execute the echo statement you got there.

If you're trying to decide whether there is a class definition in a file you could read the contents of the file (using file_get_contents or a similar function), and then scan these contents for a class definition using regular expressions or using token_get_all (see Determining what classes are defined in a PHP class file).

Community
  • 1
  • 1
wimvds
  • 12,790
  • 2
  • 41
  • 42
  • 1
    That's just not possible, including code will execute **anything** that's not contained in a function or a class. So, either don't include the file or put the echo statements inside a function/class. – wimvds Sep 28 '10 at 13:39
  • But I don't know if the file will have a class or is a simply script because I have a list of files, what I need to do is to know what of these filenames are classes or not. – CRISHK Corporation Sep 28 '10 at 13:41
  • You should mention that in your original question, we can't read minds here. If you're trying to decide whether there is a class definition in a file you could read the contents of the file (using `file_get_contents` or a similar function), and then scan these contents for a class definition using regular expressions. – wimvds Sep 28 '10 at 13:45
  • 1
    BTW Depending on what you're trying to do you could also use `token_get_all` (see http://stackoverflow.com/questions/928928/determining-what-classes-are-defined-in-a-php-class-file) – wimvds Sep 28 '10 at 13:51
  • wimvds, can you put this as an answer ? – CRISHK Corporation Sep 29 '10 at 06:32