12

例子:

类名.php

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

在另一个文件...

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

这段代码的输出是: 这将导致所有崩溃

取而代之的是: ClassName 不存在....

自动加载功能:

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

4 回答 4

12

好的,这就是它在内部的工作方式。

当您尝试使用一个不存在的类时,它会一一调用每个spl_autoload回调,直到该类存在(并且该__autoload函数就是其中之一)。如果它在链的末尾不存在,则会引发类未找到错误。

当您在class_exists没有第二个参数的情况下调用时(告诉它如果不存在就不要尝试加载它),它会调用spl_autoload回调链,直到找到类或调用最后一个方法。如果找到该类,则返回。

所以这一切都取决于你在自动加载功能中所做的事情。如果您执行以下操作:

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

它会杀死执行,并且不会按预期工作。相反,您应该这样做:

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

这就是你需要做的。

现在,您不希望执行该文件。没关系。有一个简单的解决方案。不要将该文件放在与自动加载的类相同的目录中。它违背了自动加载的目的。

唯一的其他解决方案是将类名映射存储到文件名,并以此为基础自动加载。否则它将始终执行文件(因为这是您要求它执行的操作)...

于 2010-09-28T13:42:58.397 回答
12

默认情况下,使用 class_exists 会命中自动加载器,这就是您看到问题的原因。您可以通过将第二个参数设置为 false 来绕过已注册的自动加载器。

class_exists('foo', false)

来自 PHP 文档

于 2013-01-11T00:28:16.747 回答
1

在 autoload 函数中使用 class_exists ,然后不要再使用它。这就是自动装载机的重点。

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';
    }
}
于 2010-09-28T13:03:16.003 回答
0

发生的事情是很合乎逻辑的。您的 __autoload 函数可能只包含 ClassName.php,因此它将执行您到达那里的 echo 语句。

如果您尝试确定文件中是否存在类定义,您可以读取文件的内容(使用file_get_contents或类似函数),然后使用正则表达式或使用token_get_all扫描这些内容以查找类定义(请参阅确定在 PHP 类文件中定义了哪些类)。

于 2010-09-28T13:29:21.207 回答