views:

30

answers:

4

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") ;
}
A: 

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
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
In my example, all class files are in the same directory. But yes, file check is a good idea.
AutoSponge
A: 

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

wimvds
well, how to include ClassName.php without execute echo statements ......
Cris Hong Kong CRISHK
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
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.
Cris Hong Kong CRISHK
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
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
wimvds, can you put this as an answer ?
Cris Hong Kong CRISHK
I added them to the answer.
wimvds
A: 

I tryed:

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

BUT I get a Fatal Error on ($object = new $value();) because the class is not found.

Cris Hong Kong CRISHK
If the $value class isn't found then FATAL ERROR
Cris Hong Kong CRISHK
And that's to be expected. What do you want it to do? You're trying to initialize a class that doesn't exist (which is a fatal error). Instead, do a `class_exists` which would handle it for you...
ircmaxell
A: 

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