有一种方法可以使用CLASS_EXISTS和__autoload而无需CRASH脚本吗?

CRI*_*ion 11 php exec autoload

例:

ClassName.php

<?php echo "This will crash all"; ?>
Run Code Online (Sandbox Code Playgroud)

在另一个档案中......

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

这段代码的输出是: 这会崩溃所有

而不是这样: ClassName不存在....

自动加载功能:

function __autoload( $var_class )
{
     require_once( "$var_class.php") ;
}
Run Code Online (Sandbox Code Playgroud)

irc*_*ell 12

好的,所以这里是它如何在内部工作.

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

当你在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;
}
Run Code Online (Sandbox Code Playgroud)

它将终止执行,它将无法按预期工作.相反,你应该这样做:

function __autoload($class) {
    $filename = PATH_TO_CLASSES . $class . '.php';
    if (file_exists($class)) {
        require_once $filename;
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是你需要做的.

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

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


Bri*_*ter 12

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

class_exists('foo', false)
Run Code Online (Sandbox Code Playgroud)

从PHP文档

  • 从根本上没有任何意义.为什么他们会用bool val称它为'autoload'? (2认同)

Aut*_*nge 1

在自动加载函数中使用 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';
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 嗯?不,不是... class_exists 有很多用途。其中之一是首先查看该类是否可加载(查看它是否可用)。此外,没有理由从自动加载函数中调用“class_exists”,因为您知道它还没有调用(除非有人手动调用它,但无论如何他们不应该调用它)。哦,如果我是你,我会做一些检查以确定该文件是否确实存在,然后再对其进行盲目的“require”。否则,您将无法检查类是否可加载(这对于适配器等可以派上用场)... (6认同)